Home > Java > jaxb unmarshalling by declaring types does not work when there is no namespace

jaxb unmarshalling by declaring types does not work when there is no namespace

PHPz
Release: 2024-02-06 09:09:09
forward
878 people have browsed it
Question content

I am building a parser for vast documents, which are xml documents, there is an official xsd, there are several versions: https://github.com/interactiveadvertisingbureau/ vast/tree/master

I needed to be able to unmarshal the incoming xml, so I generated the model using jaxb2-maven-plugin.

I need to be able to handle incoming xml, which may or may not mention namespaces: my problem is that it works when there is a namespace, but not when there is no namespace.

As per https://stackoverflow.com/a/8717287/3067542 and https://docs.oracle.com/javase/6/docs/api/javax/xml/bind/unmarshaller.html#unmarshalbydeclaredtype, I understand There is a workaround because I know the target class type so I can force unmarshalling to that class regardless of namespace or not.

This is my code (also available on 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());
Copy after login

When running the test, I found that the inner class was not populated:

Did I miss something? Is there an additional flag that needs to be set when generating classes using jaxb2-maven-plugin so that it can work?


Correct answer


This answer is obviously not optimized, but will give you a hint on how to make it work on version 4.2 of namespace and non-namespace xml:

Here is the body method of 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());
Copy after login

src/main/resources/xslt/vast_4.2.xslt is:

<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>
Copy after login

At this point, both unit tests apply to Section 4.2.

The above is the detailed content of jaxb unmarshalling by declaring types does not work when there is no namespace. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template