Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate @XmlRootElement Classes for Base Types in XSD?

Tags:

java

jaxb

xsd

xjc

I am having some issues with generating Java Classes with appropriate JAXB annotations from an XSD using XJC.

I have a relatively simple XSD file defining my XML schema. The complex types within the XSD take advantage of inheritance using the <xs:extension> tags. The problem I having is that I need all complex types to generate Java Classes with the @XmlRootElement.

Unfortunately, the way in which XJC generates the classes means that only derived class gets the @XmlRootElement (not the base class). I am using the simple global binding directive to ensure that it solves many of the other issues that I have faced with XJC.

Here is an example snippet of the XSD:

<xs:schema version="1.0" targetNamespace="http://www.knowledgemill.com/kmcs"   xmlns:kmcs="http://www.knowledgemill.com/kmcs"   xmlns:xs="http://www.w3.org/2001/XMLSchema"   xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"   jaxb:version="2.0"   xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"   jaxb:extensionBindingPrefixes="xjc"   elementFormDefault="qualified">     <xs:annotation>         <xs:appinfo>             <jaxb:globalBindings>                 <xjc:simple />             </jaxb:globalBindings>         </xs:appinfo>     </xs:annotation>      <xs:element name="Artifact" type="kmcs:Artifact"/>     <xs:element name="EmailArtifact" type="kmcs:EmailArtifact"/>      <xs:complexType name="Artifact">         <xs:sequence>             <xs:element name="artifactId" type="xs:string" minOccurs="0"/>             <xs:element name="artifactType" type="xs:string" minOccurs="0"/>             <xs:element name="contentHash" type="xs:string" minOccurs="0"/>         </xs:sequence>     </xs:complexType>      <xs:complexType name="EmailArtifact">         <xs:complexContent>             <xs:extension base="kmcs:Artifact">                 <xs:sequence>                     <xs:element name="subject" type="xs:string" minOccurs="0"/>                     <xs:element name="threadSubject" type="xs:string" minOccurs="0"/>                     <xs:element name="from" type="xs:string" minOccurs="0"/>                     <xs:element name="to" type="xs:string" minOccurs="0"/>                     <xs:element name="cc" type="xs:string" minOccurs="0"/>                     <xs:element name="bcc" type="xs:string" minOccurs="0"/>                     <xs:element name="messageId" type="xs:string" minOccurs="0"/>                     <xs:element name="date" type="xs:date" minOccurs="0"/>                     <xs:element name="size" type="xs:long" minOccurs="0"/>                     <xs:element name="hasAttachment" type="xs:boolean" minOccurs="0"/>                     <xs:element name="sensitivity" type="xs:string" minOccurs="0"/>                     <xs:element name="headerHash" type="xs:string" minOccurs="0"/>                 </xs:sequence>             </xs:extension>         </xs:complexContent>     </xs:complexType>   </xs:schema> 

As we can see from the above snippet, EmailArtifact extends Artifact.

The java class code for EmailArtifact contains the following:

@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "EmailArtifact", propOrder = {     "subject",     "threadSubject",     "from",     "to",     "cc",     "bcc",     "messageId",     "date",     "size",     "hasAttachment",     "sensitivity",     "headerHash" }) @XmlSeeAlso({     ExtendedEmail.class }) @XmlRootElement(name = "EmailArtifact") public class EmailArtifact     extends Artifact {      protected String subject;     protected String threadSubject;     protected String from;     protected String to;     protected String cc;     protected String bcc;     protected String messageId;     @XmlSchemaType(name = "date")     protected XMLGregorianCalendar date;     protected Long size;     protected Boolean hasAttachment;     protected String sensitivity;     protected String headerHash; 

The java class code for Artifact contains the following:

@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "Artifact", propOrder = {     "artifactId",     "artifactType",     "contentHash" }) @XmlSeeAlso({     ManagedDocArtifact.class,     EmailArtifact.class }) public class Artifact {      protected String artifactId;     protected String artifactType;     protected String contentHash; 

In the EmailArtifact we can see that it contains the @XmlRootElement but the base type Artifact does not contain @XmlRootElement.

How can you force XJC to generate @XmlRootElement for all classes including the base types.

like image 892
jallch Avatar asked Oct 03 '09 15:10

jallch


People also ask

How do you use XJC generated classes?

Open a command prompt. Run the JAXB schema compiler, xjc command from the directory where the schema file is located. The xjc schema compiler tool is located in the app_server_root \bin\ directory. Use the generated JAXB objects within a Java application to manipulate XML content through the generated JAXB classes.

How do I generate JAXB classes from XSD in Intellij community?

Generate a Java class from an XML Schema using JAXB In the active editor tab, open the desired Schema . xsd file or an XML document, which contains the desired Schema. In the main menu, go to Tools | XML Actions | Generate Java Code From XML Schema Using JAXB.

What is XJC?

XJC is a Java SE tool that compiles an XML schema file into fully annotated Java classes. It is distributed within the JDK package and is located at /bin/xjc path.


2 Answers

Just bind using xjb-file:

<?xml version="1.0"?> <jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">   <jxb:bindings schemaLocation="path/to/myschema.xsd" node="/xs:schema">     <jxb:globalBindings>       <xjc:simple />     </jxb:globalBindings>   </jxb:bindings> </jxb:bindings> 

And don't forget to define element of the same type:

<xs:complexType name="Artifact" /> <xs:element name="artifact" type="Artifact"> 
like image 52
Azee Avatar answered Oct 21 '22 17:10

Azee


This question references a blog post by Kohsuke Kawaguchi, formerly worked on the JAX-B or JAX-WS RI, that talks about the RI's decision making process and lack of clarity on this issue in the spec.

The blog post mentions that the simple binding feature is part of the RI. Are you using the RI to generate your code?

like image 22
DavidValeri Avatar answered Oct 21 '22 16:10

DavidValeri