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?
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>
Related videos on Youtube
supertonsky
Updated on June 04, 2022Comments
-
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.