Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAXB not creating class for empty xs:element tag

Tags:

java

xml

jaxb

xsd

I am migrating a project from jaxb 1.0 to 2.1. When generating classes from an xsd using jaxb 2.1 (via an ant xjc task), the generated classes are missing elements which don't have any content like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified">
....
<xs:element name="get-all-services-partners-request"/>

However files are generated when the element does have content, like this:

 <xs:element name="catalog-full-service-request">
   <xs:complexType>
     <xs:sequence>
       <xs:element name="service-id" type="xs:string" minOccurs="0"/>
       <xs:element name="log-id" type="xs:string" minOccurs="0"/>
     </xs:sequence>
   </xs:complexType>
 </xs:element>

Why would this be? A previous set of generated classes (using jaxb 1.0) contain classes for all elements, not just those with content.

How do I get jaxb to generate these missing classes? I don't really have rights to change the xsd (but could do so if really necessary).

like image 521
mdarwin Avatar asked Dec 03 '25 17:12

mdarwin


1 Answers

The good news is you don't need to generate the "missing classes", I'll demonstrate below with an example.

schema.xsd

Below is a simplified version of your XML schema.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="unqualified">

    <xs:element name="get-all-services-partners-request" />

    <xs:complexType name="foo">
        <xs:sequence>
            <xs:element name="bar" type="xs:string" />
        </xs:sequence>
    </xs:complexType>

</xs:schema>

Foo

A JAXB (JSR-222) implementation will create a class per complex type (named or anonymous). In the above XML schema there is only one complex type (foo) so only on model class is generated.

package forum12990635;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "foo", propOrder = {
    "bar"
})
public class Foo {

    @XmlElement(required = true)
    protected String bar;

    public String getBar() {
        return bar;
    }

    public void setBar(String value) {
        this.bar = value;
    }

}

ObjectFactory

Global elements corresponding to named complex types corresond to @XmlElementDecl annotations on a class annotated with @XmlRegistry (see: http://blog.bdoughan.com/2012/07/jaxb-and-root-elements.html).

package forum12990635;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;


@XmlRegistry
public class ObjectFactory {

    private final static QName _GetAllServicesPartnersRequest_QNAME = new QName("", "get-all-services-partners-request");

    public ObjectFactory() {
    }

    public Foo createFoo() {
        return new Foo();
    }

    @XmlElementDecl(namespace = "", name = "get-all-services-partners-request")
    public JAXBElement<Object> createGetAllServicesPartnersRequest(Object value) {
        return new JAXBElement<Object>(_GetAllServicesPartnersRequest_QNAME, Object.class, null, value);
    }

}

Demo

Below is an example of how to create a document with the root element get-all-services-partners-request.

package forum12990635;

import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance("forum12990635");

        Foo foo = new Foo();
        foo.setBar("Hello World");

        ObjectFactory objectFactory = new ObjectFactory();
        JAXBElement<Object> jaxbElement = objectFactory.createGetAllServicesPartnersRequest(foo);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(jaxbElement, System.out);
    }

}

Output

Below is the output from running the demo code.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<get-all-services-partners-request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="foo">
    <bar>Hello World</bar>
</get-all-services-partners-request>
like image 145
bdoughan Avatar answered Dec 06 '25 07:12

bdoughan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!