2017-02-17 27 views
8

Tôi có đối tượng cây JAXB khá phức tạp. Đối mỗi lá nút, tôi cần phải lọc giá trị thực tế của nóJAXB marshalling: Giá trị lọc của các phần tử lá

Ví dụ:

nút
<Book> 
    <Title>Yogasana Vijnana: the Science of Yoga</Title> 
    <Author>Dhirendra Brahmachari</Author> 
    <Date>1966</Date> 
</Book> 

Chiếc lá ở đây sẽ là Title, authorDate.
Hãy tưởng tượng rằng tôi cần một tài liệu marshalled cho mô hình JAXB này với ký tự đầu tiên lấy ra cho mỗi nút lá:

<Book> 
    <Title>ogasana Vijnana: the Science of Yoga</Title> 
    <Author>hirendra Brahmachari</Author> 
    <Date>966</Date> 
</Book> 


phương pháp tốt nhất là gì?
Tôi thấy hai điểm bắt đầu, tuy nhiên, tôi hiện đang bị kẹt.

1. Do sự thay đổi trong mô hình JAXB
Có một số mechnism traversal mà tôi có thể sử dụng để có được các yếu tố lá của bất kỳ đối tượng JAXB (một số loại mô hình của khách hay cái gì)?

2. Móc vào đầm lầy
Có thể chúng ta có thể móc vào đầm lầy, ví dụ: sử dụng số XMLStreamWriter ..

Có giải pháp thanh lịch cho loại vấn đề này không?

Trả lời

9

Một cách tiếp cận dựa trên một trang trí loại XMLStreamWriter chỉ đơn giản là bỏ qua ký tự đầu tiên của nội dung văn bản, tuy nhiên bạn sẽ không có khả năng giới hạn nó chỉ với các nút lá, nó sẽ áp dụng cùng một logic cho tất cả các nội dung văn bản không chỉ của các nút lá mà sẽ không là một vấn đề nếu marshalling của bạn không tạo ra nội dung hỗn hợp như trong ví dụ của bạn. Thật vậy nếu bạn không có nội dung hỗn hợp (nội dung văn bản và các nút kết hợp với nhau), chỉ có các nút lá có thể có nội dung văn bản.

bạn trang trí có thể là một cái gì đó như thế này:

public class RemoveFirstCharacter implements XMLStreamWriter { 

    private final XMLStreamWriter delegate; 

    public RemoveFirstCharacter(final XMLStreamWriter delegate) { 
     this.delegate = delegate; 
    } 

    @Override 
    public void writeStartElement(final String localName) throws XMLStreamException { 
     delegate.writeStartElement(localName); 
    } 

    @Override 
    public void writeStartElement(final String namespaceURI, final String localName) 
     throws XMLStreamException { 
     delegate.writeStartElement(namespaceURI, localName); 
    } 

    ... 

    @Override 
    public void writeCharacters(final String text) throws XMLStreamException { 
     // Skip the first character 
     delegate.writeCharacters(text.substring(1)); 
    } 

    @Override 
    public void writeCharacters(final char[] text, final int start, final int len) 
     throws XMLStreamException { 
     if (start == 0) { 
      // Skip the first character 
      delegate.writeCharacters(text, 1, len - 1); 
     } else { 
      delegate.writeCharacters(text, start, len); 
     } 
    } 
} 

Sau đó, mã của bạn sẽ là:

// Create the marshaller for the class Book 
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class); 
Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

// Create the main XMLStreamWriter 
XMLOutputFactory output = XMLOutputFactory.newInstance(); 
XMLStreamWriter writer = output.createXMLStreamWriter(System.out); 

// Apply the custom XMLStreamWriter that will remove the first character 
// of each text content 
jaxbMarshaller.marshal(book, new RemoveFirstCharacter(writer)); 
6

Bạn có thể sau quá trình kết quả XML để loại bỏ các ký tự đầu tiên của nội dung văn bản của mỗi nút lá sử dụng XSLT với kiểu tiếp theo:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="*"> 
     <xsl:copy> 
      <xsl:apply-templates/> 
     </xsl:copy> 
    </xsl:template> 
    <!-- For each text content of leaf nodes (nodes without child nodes) --> 
    <xsl:template match="*[not(*)]/text()"> 
     <!-- Skip the first character --> 
     <xsl:value-of select="substring(., 2)"/> 
    </xsl:template> 
</xsl:stylesheet> 

Theo kích thước của kết quả của bạn XML bạn có thể giữ kết quả vào bộ nhớ trước khi áp dụng biểu định kiểu hoặc lưu trữ trước kết quả là XML vào tệp tạm thời.

Sau đây là cách mã của bạn có thể được giả định rằng kết quả XML thể phù hợp với bộ nhớ:

// Create the marshaller for the class Book 
JAXBContext jaxbContext = JAXBContext.newInstance(Book.class); 
Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 

// Make the output being pretty printed 
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

// Marshall the book instance and keep the result into a ByteArrayOutputStream 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
jaxbMarshaller.marshal(book, out); 

TransformerFactory factory = TransformerFactory.newInstance(); 
// Define the stylesheet to apply 
Transformer transformer = factory.newTransformer(new StreamSource(xsltFile)); 
// Define the input XML content 
Source text = new StreamSource(new ByteArrayInputStream(out.toByteArray())); 
// Apply the stylesheet and store the content into outputFile 
transformer.transform(text, new StreamResult(outputFile)); 

Output:

<?xml version="1.0" encoding="UTF-8"?> 
<Book> 
    <Title>ogasana Vijnana: the Science of Yoga</Title> 
    <Author>hirendra Brahmachari</Author> 
    <Date>966</Date> 
</Book> 
Các vấn đề liên quan