通过 xslt 使用 JAXB 解组 CData

CData unmarshalling with JAXB over xslt

我正在尝试使用 xsl 转换转换第三方 xml,然后使用 JAXB 将结果 xml 转换为 java 对象。 但是标记为 CDATA 的元素内容之间的某些地方会丢失。

这是我的示例第三方 xml

<person>
   <name>aName</name>
</person>

XSL 转换

<xsl:template match="/">
    <User>
        <personName><xsl:value-of select="//name"/></personName>
        <!-- Saving input xml as CDATA for future ref -->
        <inputXml>
            <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
            <xsl:copy-of select="."/>
            <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
        </inputXml>     
    </User>
</xsl:template>

Java Class

@XmlRootElement
public class User{
    @XmlElement
    public String personName;
    @XmlElement
    public String inputXml
}

翻译

    JAXBResult jaxbResult = new JAXBResult(JAXBContext.newInstance(User.class));
    newXslTransformer().transform(new StreamSource(thirdPatyXmlFile), jaxbOutput);
    User user = (User)jaxbResult.getResult();
    System.out.println(user.inputXml);

但上面的代码将 inputXml 输出为 ]]>。 如果我按如下方式对 CDATA 进行硬编码,我将能够获得 inputXml,但当我动态生成它时却无法获得。

<inputXml><![CDATA[<person><name>aName</name></person>]]></inputXml>

如有任何建议,我们将不胜感激。

A JAXBResult 是一个 SAXResult,因此转换结果作为一系列 SAX 事件发出,JAXB 解组器使用它们来构造您的 User 对象。

这是一种有效的技术,可以避免稍后在解组时编写转换和重新解析。

不幸的是,您的 CDATA hack 并不适用于此。 在 <inputXml> 中,JAXBResult 的 ContentHandler 看到文本 "<![CDATA[",然后您的整个输入文档作为一系列元素和文本事件,然后是结束文本事件 "]]>" - 最后一个被使用作为 User.inputXml.

的值

看来您需要转换为内存缓冲区,然后从中解组。