How do I set the elementFormDefault of an Element in JAXB on a single class basis instead of having it set for the entire package?

10,768

TL;DR

When elementFormDefault=XmlNsForm.QUALIFIED is set on @XmlSchema, you can override then namespace for the properties of a class by annotating it with @XmlType(namespace="ANOTHER_NAMESPACE"). If you want to override the namespace for a root element you can do @XmlRootElement(namespace="DIFFERENT_NAMESPACE).

For More Information


JAVA MODEL

Bar

You just need to set the namespace on the @XmlType annotation for the Bar class.

package forum14579814;

import javax.xml.bind.annotation.XmlType;

@XmlType(namespace="FOO")
public class Bar {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

package-info

This will override the namespace that you specified in package level @XmlSchema annotation.

@XmlSchema(namespace="FOO2", elementFormDefault=XmlNsForm.QUALIFIED)
package forum14579814;

import javax.xml.bind.annotation.*;

Foo

This object is the root of your domain model.

package forum14579814;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Foo {

    private Bar bar;

    public Bar getBar() {
        return bar;
    }

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

}

XML SCHEMAS

Below are the XML schemas that you provided via http://jsfiddle.net/supertonsky/Phck5/.

Foo.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="FOO2"
    xmlns:tns="FOO2" 
    xmlns:tns2="FOO"
    elementFormDefault="qualified">
    <import namespace="FOO" schemaLocation="BAR.xsd"></import>
    <element name="foo" type="tns:Foo"></element>
    <complexType name="Foo">
        <sequence>
            <element name="bar" type="tns2:Bar"></element>
        </sequence>
    </complexType>
</schema>

Bar.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="FOO"
    xmlns:tns="FOO" 
    elementFormDefault="qualified">
    <complexType name="Bar">
        <sequence>
            <element name="name" type="string" maxOccurs="1" nillable="true"></element>
        </sequence>
    </complexType>
</schema>

DEMO CODE

The following demo code will create an instance of the domain object and output it to XML. The XML output will be validated during the marshal operation against the XML schemas that you provided.

package forum14579814;

import java.io.File;

import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.validation.*;

public class Demo {

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

        Bar bar = new Bar();
        bar.setName("BAR");

        Foo foo = new Foo();
        foo.setBar(bar);

        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(new File("src/forum14579814/Foo.xsd"));

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

}

Output

Then you would get the following output. Note how the name element that corresponds to the name property on Bar is qualified with the FOO namespace while all the other elements are qualified with the FOO2 namespace.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:foo xmlns="FOO" xmlns:ns2="FOO2">
    <ns2:bar>
        <name>BAR</name>
    </ns2:bar>
</ns2:foo>
Share:
10,768

Related videos on Youtube

supertonsky
Author by

supertonsky

Updated on June 04, 2022

Comments

  • supertonsky
    supertonsky almost 2 years

    I know I could use @XmlSchema to do this but the problem is we have a class in the same package that needs its namespace to be different from what's defined on package-info.java. So we declared the namespace in @XmlRootElement instead (of course while still having @XmlSchema in place). But doing this will not allow us to set the class's elementFormDefault. Moving the class to a different package is not an option. Basically, I just want to override the namespace for this particular class.