当没有命名空间时,通过声明类型进行的 jaxb 解组不起作用

问题描述 投票:0回答:1

我正在为 VAST 文档构建一个解析器,这些文档是 XML 文档,有一个官方 XSD,有几个版本:https://github.com/InteractiveAdvertisingBureau/vast/tree/master

我需要能够解组传入的 XML,因此我使用

jaxb2-maven-plugin
生成了模型。

我需要能够处理传入的 XML,可能会或可能不会提到命名空间:我的问题是,当有命名空间时它可以工作,但当没有命名空间时它就不起作用。

以下https://stackoverflow.com/a/8717287/3067542https://docs.oracle.com/javase/6/docs/api/javax/xml/bind/Unmarshaller.html#unmarshalByDeclaredType,我知道有一个解决方法,因为我知道目标类类型,所以我可以强制解组到该类,无论是否有命名空间。

这是我的代码(也可以在 github 上找到

JAXBContext jc = JAXBContext.newInstance(VAST.class);
Unmarshaller u = jc.createUnmarshaller();

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);

DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(xmlString)));
JAXBElement<VAST> foo = u.unmarshal( doc, VAST.class);

return new CustomVast(foo.getValue());

运行测试时,我发现内部类未填充:

我错过了什么吗?使用

jaxb2-maven-plugin
生成类时是否需要设置一个额外的标志,以便它可以工作?

java xml jaxb maven-jaxb2-plugin vast
1个回答
0
投票

这个答案显然没有优化,但会提示您如何让它在 4.2 版本的命名空间和非命名空间 XML 上工作:

这里是

parseXml

的body方法
JAXBContext jc = JAXBContext.newInstance(VAST.class);
Unmarshaller u = jc.createUnmarshaller();

// should be optimized
TransformerFactory tf = TransformerFactory.newInstance();
StringWriter sw = new StringWriter();
URL urlXslt = VastParser.class.getClassLoader().getResource("xslt/vast_4.2.xslt");
File fileXslt = new File(urlXslt.toURI());
Transformer t = tf.newTransformer(new StreamSource(new FileInputStream(fileXslt)));
// transform original XML with XSLT to always add the namespace in the parsing 
t.transform(new StreamSource(new StringReader(xmlString)), new StreamResult(sw));

// unmarshall transformed XML
JAXBElement<VAST> foo = u.unmarshal(new StreamSource(new StringReader(sw.toString())), VAST.class);

return new CustomVast(foo.getValue());

src/main/resources/xslt/vast_4.2.xslt
是:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|text()|comment()|processing-instruction()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- adds the xmlns part to the VAST element -->
    <xsl:template match="/VAST">
        <VAST xmlns="http://www.iab.com/VAST">
            <xsl:apply-templates select="@*|node()"/>
        </VAST>
    </xsl:template>

    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这样,两个单元测试都适用于 4.2 部分。

© www.soinside.com 2019 - 2024. All rights reserved.