我正在为 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中文网其他相关文章!