{title:'Namespaces'}

Let's go back to the example of our original Person bean class but add some namespace annotations:

Sample Beans

| @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:

package-info.java

| @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;

Sample Code

| 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();