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

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

PHPz
PHPz转载
2024-02-06 09:09:09865浏览
问题内容

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

我需要能够解组传入的 xml,因此我使用 jaxb2-maven-plugin 生成了模型。

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

按照https://stackoverflow.com/a/8717287/3067542和https://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 生成类时是否需要设置一个附加标志,以便它可以工作?


正确答案


这个答案显然没有优化,但会提示您如何让它在 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 部分。

以上是当没有命名空间时,通过声明类型进行的 jaxb 解组不起作用的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除