Ich baue einen Parser für umfangreiche Dokumente, bei denen es sich um XML-Dokumente handelt, es gibt eine offizielle XSD, es gibt mehrere Versionen: https://github.com/interactiveadvertisingbureau/vast/tree/master
Ich musste in der Lage sein, die eingehende XML-Datei zu entmarshalieren, also habe ich das Modell mit jaxb2-maven-plugin
generiert.
Ich muss in der Lage sein, eingehende XML-Dateien zu verarbeiten, in denen möglicherweise Namespaces erwähnt werden oder auch nicht: Mein Problem ist, dass es funktioniert, wenn ein Namespace vorhanden ist, aber nicht, wenn kein Namespace vorhanden ist.
Wenn ich https://stackoverflow.com/a/8717287/3067542 und https://docs.oracle.com/javase/6/docs/api/javax/xml/bind/unmarshaller.html#unmarshalbydeclaredtype folge, verstehe ich, dass dies der Fall ist Eine Problemumgehung: Da ich den Zielklassentyp kenne, kann ich das Unmarshalling für diese Klasse erzwingen, unabhängig davon, ob der Namespace vorhanden ist oder nicht.
Das ist mein Code (auch auf Github verfügbar)
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());
Als ich den Test durchführte, stellte ich fest, dass die innere Klasse nicht gefüllt war:
Habe ich etwas verpasst? Muss ich beim Generieren einer Klasse mit jaxb2-maven-plugin
ein zusätzliches Flag setzen, damit es funktioniert?
Diese Antwort ist offensichtlich nicht optimiert, gibt Ihnen aber einen Hinweis, wie Sie sie auf der 4.2-Version von Namespace- und Nicht-Namespace-XML zum Laufen bringen können:
Hier ist die Körpermethode von 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
ist:
<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>
Zu diesem Zeitpunkt gelten beide Komponententests für Abschnitt 4.2.
Das obige ist der detaillierte Inhalt vonDas Jaxb-Unmarshalling durch die Deklaration von Typen funktioniert nicht, wenn kein Namespace vorhanden ist. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!