Let's go back to the example of our original Person bean class but add some namespace annotations:
| @Xml(prefix="per")
| @Bean(typeName="person")
| public class Person {
|
| // Bean properties
| public String name;
| @Swap(TemporalCalendarSwap.IsoInstant.class) public Calendar birthDate;
| public List<Address> addresses;
|
| // Getters/setters omitted
| }
|
| @Xml(prefix="addr")
| @Bean(typeName="address")
| public class Address {
|
| // Bean properties
| @Xml(prefix="mail") public String street, city;
| @Xml(prefix="mail") public StateEnum state;
| @Xml(prefix="mail") public int zip;
| public boolean isCurrent;
|
| // Getters/setters omitted
| }
The namespace URLs can either be defined as part of the {@link oaj.xml.annotation.Xml @Xml}
annotation, or can be defined at the package level with the {@link oaj.xml.annotation.XmlSchema @XmlSchema}
annotation.
Below shows it defined at the package level:
| @XmlSchema(
| prefix="ab", // Default namespace
| xmlNs={
| @XmlNs(prefix="ab", namespaceURI="http://www.apache.org/addressBook/"),
| @XmlNs(prefix="per", namespaceURI="http://www.apache.org/person/"),
| @XmlNs(prefix="addr", namespaceURI="http://www.apache.org/address/"),
| @XmlNs(prefix="mail", namespaceURI="http://www.apache.org/mail/")
| }
| )
| package org.apache.juneau.examples.addressbook;
| Person person = new Person()
| .name("John Smith")
| .birthDate("1946-08-12T00:00:00Z")
| .addresses(
| new Address()
| .street("100 Main Street")
| .city("Anywhereville")
| .state(NY)
| .zip(12345)
| .isCurrent(true);
| );
|
| // Create a new serializer with readable output, this time with namespaces enabled.
| // Note that this is identical to XmlSerializer.DEFAULT_NS_SQ_READABLE.
| XmlSerializer serializer = XmlSerializer.create().ns().ws().sq().build();
|
| String xml = serializer.serialize(p);
Now when we run this code, we'll see namespaces added to our output:
| <per:person>
| <per:name>John Smith</per:name>
| <per:birthDate>1946-08-12T04:00:00Z</per:birthDate>
| <per:addresses>
| <addr:address>
| <mail:street>100 Main Street</mail:street>
| <mail:city>Anywhereville</mail:city>
| <mail:state>NY</mail:state>
| <mail:zip>12345</mail:zip>
| <addr:isCurrent>true</addr:isCurrent>
| </addr:address>
| </per:addresses>
| </per:person>
Enabling the XmlSerializer.XML_addNamespaceUrisToRootsetting results
in the namespace URLs being added to the root node:
| <per:person
| xmlns='http://www.apache.org/2013/Juneau'
| xmlns:per='http://www.apache.org/person/'
| xmlns:addr='http://www.apache.org/address/'
| xmlns:mail='http://www.apache.org/mail/'
| >
| <per:name>John Smith</per:name>
| <per:birthDate>1946-08-12T04:00:00Z</per:birthDate>
| <per:addresses>
| <addr:address>
| <mail:street>100 Main Street</mail:street>
| <mail:city>Anywhereville</mail:city>
| <mail:state>NY</mail:state>
| <mail:zip>12345</mail:zip>
| <addr:isCurrent>true</addr:isCurrent>
| </addr:address>
| </per:addresses>
| </per:person>
We can simplify the output by setting the default namespace on the serializer so that all the elements do
not need to be prefixed:
| // Create a new serializer with readable output, this time with namespaces enabled.
| XmlSerializer serializer = XmlSerializer.create().ws().sq().ns()
| .defaultNamespaceUri("http://www.apache.org/person/")
.build();
|
This produces the following equivalent where the elements don't need prefixes since they're already in the
default document namespace:
| <person
| xmlns:juneau='http://www.apache.org/2013/Juneau'
| xmlns='http://www.apache.org/person/'
| xmlns:addr='http://www.apache.org/address/'
| xmlns:mail='http://www.apache.org/mail/'
| >
| <name>John Smith</name>
| <birthDate>1946-08-12T04:00:00Z</birthDate>
| <addresses>
| <addr:address>
| <mail:street>100 Main Street</mail:street>
| <mail:city>Anywhereville</mail:city>
| <mail:state>NY</mail:state>
| <mail:zip>12345</mail:zip>
| <addr:isCurrent>true</addr:isCurrent>
| </addr:address>
| </addresses>
| </person>
By default, the XML serializer class will make a first-pass over the data structure to look for namespaces
defined on classes and bean properties.
In high-performance environments, you may want to consider disabling auto-detection and providing your
own explicit list of namespaces to the serializer to avoid this scanning step using
{@link oaj.xml.XmlSerializer.Builder#disableAutoDetectNamespaces()}.
The following code will produce the same output as before but will perform slightly better since it
avoids this pre-scan step.
| // Create a new serializer with readable output, this time with namespaces enabled.
| XmlSerializer serializer = XmlSerializer.create()
| .ws()
| .sq()
| .autoDetectNamespaces(false)
| .namespaces("{per:'http://www.apache.org/person/'}")
| .build();