Jaxb2 generate classes with @XMLRootElement tag

68 views Asked by At

I am using Jaxb2 plugin to generate JAVA class files from XSD files

Here is my plugin config

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>jaxb2-maven-plugin</artifactId>
            <version>2.5.0</version>
            <executions>
                <execution>
                    <id>parentA</id>
                    <goals>
                        <goal>xjc</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <sources>
                    <source>src/test/resources/xsd/parent.xsd</source>
                </sources>
                <packageName>com.sample.generated</packageName>
                <clearOutputDir>false</clearOutputDir>
            </configuration>
        </plugin>

Here is my sample XSD file:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1"
           attributeFormDefault="qualified"
           elementFormDefault="qualified">
    <xs:include schemaLocation="../contracts/childc.xsd"/>
    <xs:include schemaLocation="../contracts/childa.xsd"/>
    <xs:include schemaLocation="../contracts/childb.xsd"/>
    <xs:element name="parent">
        <xs:complexType>
            <xs:annotation>
                                <xs:appinfo>
                                    <jaxb:class name="ParentA"/>
                                </xs:appinfo>
                <xs:documentation>Parent profile</xs:documentation>
            </xs:annotation>
            <xs:sequence>
                <xs:element name="name" type="xs:string"/>
                <xs:element name="birthPlace" type="xs:string"/>
                <xs:element ref="childA"/>
                <xs:element ref="childB"/>
                <xs:element ref="childC"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

I am specifying the name of the class file that needs to generated using following config in XSD file.

<xs:appinfo>
   <jaxb:class name="ParentA"/>
</xs:appinfo>

Here is am sample XML file I am trying to unMarshall

<parentA>
    <name>SAM</name>
    <birthPlace>Dallas</birthPlace>
    <childA>..</childA>
    <childB>..</childB>
    <childC>...</childC>
</parentA>

Here is the logic to un marshall Above XML

JAXBContext jaxbContext = JAXBContext.newInstance(parentA.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
parentA parentData = (parentA) jaxbUnmarshaller.unmarshal(xml.getBinaryStream());
//Assert on parentData
  • When I run jaxB2:XJC a Java file is generated with name as "parentA"
  • But the generated file don't have the annotation @XmlRootElement(name ="parentA") at top of class.
  • Because of which during un marshalling I am seeing an error.

Question:

  • what additional config I need to add to XSD file so that the generated XML file will have @RootElement tag
1

There are 1 answers

0
Laurent Schoelens On

Removing the following in the XSD makes it works

<xs:appinfo>
   <jaxb:class name="ParentA"/>
</xs:appinfo>

You'll have the following class generated (but not with the desired name).

@XmlRootElement(name = "parent")
public class Parent

Since you declared the xsd:element with parent name, you should then try to unmarshal the following XML

<parent>
    <name>SAM</name>
    <birthPlace>Dallas</birthPlace>
    <childA>..</childA>
    <childB>..</childB>
    <childC>...</childC>
</parent>

Tested against the org.jvnet.jaxb:jaxb-maven-plugin, without the childX element (since reference in unprovided XSD), unmarshall / marshall was successful with XML parent tag name.

Output of marshalling : context.createMarshaller().marshal(dto, System.out);

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parent><name>SAM</name><birthPlace>Dallas</birthPlace></parent>

If you still want parentA as tag name, you should change the name tag from parent to parentA in your XSD, the rest will still work like above with parent replaced by parentA.