Heim  >  Artikel  >  Das Jaxb-Unmarshalling durch die Deklaration von Typen funktioniert nicht, wenn kein Namespace vorhanden ist

Das Jaxb-Unmarshalling durch die Deklaration von Typen funktioniert nicht, wenn kein Namespace vorhanden ist

PHPz
PHPznach vorne
2024-02-06 09:09:09824Durchsuche
Frageninhalt

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?


Richtige Antwort


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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen