我正在為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中文網其他相關文章!