JAXB编组:过滤叶元素的值

时间:2017-02-17 15:02:48

标签: java xml jaxb marshalling

我有一个相当复杂的JAXB树对象。 对于每个叶子节点,我需要过滤其实际值

E.g。

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

此处的叶节点为TitleauthorDate 想象一下,我需要为此JAXB模型编写一个编组文档,并为每个叶节点删除第一个字符:

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


什么是最好的方法? 我看到了两个起点,但是,我现在卡住了。

1。在JAXB模型中进行更改
是否有一些遍历机制可以用来获取任何JAXB对象的叶元素(某种访问者模式或其他东西)?

2。陷入编组
也许我们可以进入编组,例如使用XMLStreamWriter ..

这种问题是否有优雅的解决方案?

1 个答案:

答案 0 :(得分:6)

您可以后处理生成的XML,使用XSLT删除每个叶节点的文本内容的第一个字符,并使用下一个样式表:

<?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>

根据结果XML的大小,您可以在应用样式表之前将结果保留在内存中,或者将生成的XML存储到临时文件中。

以下是您的代码如何假设生成的XML可以适合内存:

// 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));

<强>输出:

<?xml version="1.0" encoding="UTF-8"?>
<Book>
    <Title>ogasana Vijnana: the Science of Yoga</Title>
    <Author>hirendra Brahmachari</Author>
    <Date>966</Date>
</Book>