Je construis un analyseur pour de vastes documents, qui sont des documents XML, il existe un xsd officiel, il existe plusieurs versions : https://github.com/interactiveadvertisingbureau/vast/tree/master
J'avais besoin de pouvoir désorganiser le XML entrant, j'ai donc généré le modèle en utilisant jaxb2-maven-plugin
.
Je dois être capable de gérer le XML entrant, qui peut ou non mentionner des espaces de noms : mon problème est que cela fonctionne lorsqu'il y a un espace de noms, mais pas lorsqu'il n'y a pas d'espace de noms.
Suite à https://stackoverflow.com/a/8717287/3067542 et https://docs.oracle.com/javase/6/docs/api/javax/xml/bind/unmarshaller.html#unmarshalbydeclaredtype, je comprends qu'il y a une solution de contournement, puisque je connais le type de classe cible, je peux forcer la désorganisation de cette classe, espace de noms ou non.
Voici mon code (également disponible sur 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());
Lors de l'exécution du test, j'ai constaté que la classe interne n'était pas renseignée :
Est-ce que j'ai raté quelque chose ? Y a-t-il un indicateur supplémentaire que je dois définir lors de la génération d'une classe à l'aide de jaxb2-maven-plugin
pour qu'elle puisse fonctionner ?
Cette réponse n'est évidemment pas optimisée, mais vous donnera un indice sur la façon de la faire fonctionner sur la version 4.2 de l'espace de noms et du XML non-espace de noms :
Voici la méthode corporelle de parsexml
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
est :
<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>
À ce stade, les deux tests unitaires sont applicables à la section 4.2.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!