http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/4fb01038/juneau-core/src/main/java/org/apache/juneau/xml/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/package.html
b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
index 92d985c..11a4978 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
@@ -59,15 +59,16 @@
<ol class='toc'>
<li><p><a class='doclink' href='#Overview'>XML support overview</a></p>
<ol>
- <li><p><a class='doclink'
href='#OverviewExample'>Example</a></p>
+ <li><p><a class='doclink' href='#OverviewExample'>XML support
overview - example</a></p>
</ol>
<li><p><a class='doclink' href='#XmlSerializer'>XmlSerializer
class</a></p>
<ol>
+ <li><p><a class='doclink' href='#Methodology'>XML support
methodology</a></p>
<li><p><a class='doclink' href='#XmlAnnotation'>@Xml
annotations</a></p>
<ol>
+ <li><p><a class='doclink'
href='#XmlName'>@Bean.typeName()</a></p>
<li><p><a class='doclink'
href='#XmlChildName'>@Xml.childName()</a></p>
<li><p><a class='doclink'
href='#XmlFormat'>@Xml.format()</a></p>
- <li><p><a class='doclink'
href='#XmlContentHandler'>@Xml.contentHandler()</a></p>
</ol>
<li><p><a class='doclink' href='#Namespaces'>Namespaces</a></p>
<ol>
@@ -83,9 +84,6 @@
<li><p><a class='doclink' href='#XmlParser'>XmlParser class</a></p>
<ol>
<li><p><a class='doclink' href='#GenericParsing'>Parsing into
generic POJO models</a></p>
- <ol>
- <li><p><a class='doclink'
href='#AddJsonTypeAttr'>Serializing with JSON-type attributes</a></p>
- </ol>
<li><p><a class='doclink'
href='#ParserConfigurableProperties'>Configurable properties</a></p>
<li><p><a class='doclink' href='#ParserOtherNotes'>Other
notes</a></p>
</ol>
@@ -102,6 +100,7 @@
</ol>
</ol>
+
<!--
========================================================================================================
-->
<a id="Overview"></a>
<h2 class='topic' onclick='toggle(this)'>1 - XML support overview</h2>
@@ -130,7 +129,7 @@
These transforms can be associated with serializers/parsers, or
can be associated with classes or bean properties through type and method
annotations.
</p>
<p>
- Refer to <a href='../package-summary.html#PojoCategories'
class='doclink'>POJO Categories</a> for a complete definition of supported
POJOs.
+ Refer to <a
href='../../../../overview-summary.html#Core.PojoCategories'
class='doclink'>POJO Categories</a> for a complete definition of supported
POJOs.
</p>
<p>
While annotations are not required to produce or consume XML,
several XML annotations are provided
@@ -147,7 +146,7 @@
<h3 class='topic' onclick='toggle(this)'>1.1 - XML support overview -
example</h3>
<div class='topic'>
<p>
- The example shown here is from the Address Book
resource located in the <code>org.apache.juneau.sample.war</code>
application.<br>
+ The example shown here is from the Address Book
resource located in the <code>juneau-samples</code> microservice project.<br>
The POJO model consists of a <code>List</code> of
<code>Person</code> beans, with each <code>Person</code> containing
zero or more <code>Address</code> beans.
</p>
@@ -176,6 +175,7 @@
</div>
</div>
+
<!--
========================================================================================================
-->
<a id="XmlSerializer"></a>
<h2 class='topic' onclick='toggle(this)'>2 - XmlSerializer class</h2>
@@ -192,11 +192,9 @@
<li>{@link org.apache.juneau.xml.XmlSerializer#DEFAULT} - All
default settings.
<li>{@link org.apache.juneau.xml.XmlSerializer#DEFAULT_SQ} -
Use single quotes on attributes. Typically useful for testing since it makes
string comparison simpler.
<li>{@link
org.apache.juneau.xml.XmlSerializer#DEFAULT_SQ_READABLE} - Use single quotes on
attributes and add whitespace for readability.
- <li>{@link org.apache.juneau.xml.XmlSerializer#DEFAULT_XMLJSON}
- Add JSON attribute tags on non-String values for full JSON equivalency.
- <li>{@link
org.apache.juneau.xml.XmlSerializer#DEFAULT_XMLJSON_SQ} - Same as
DEFAULT_XMLJSON, but use single quotes on attributes.
- <li>{@link org.apache.juneau.xml.XmlSerializer#DEFAULT_SIMPLE}
- Don't serialize XML namespaces.
- <li>{@link
org.apache.juneau.xml.XmlSerializer#DEFAULT_SIMPLE_SQ} - Same as
DEFAULT_SIMPLE, but use single quotes on attributes.
- <li>{@link
org.apache.juneau.xml.XmlSerializer#DEFAULT_SIMPLE_XMLJSON_SQ} - Same as
DEFAULT_XMLJSON, but ignore XML namespaces and use single quotes on attributes.
+ <li>{@link org.apache.juneau.xml.XmlSerializer#DEFAULT_NS} -
Same as DEFAULT but with namespaces enabled.
+ <li>{@link org.apache.juneau.xml.XmlSerializer#DEFAULT_NS_SQ} -
Same as DEFAULT_SQ but with namespaces enabled.
+ <li>{@link
org.apache.juneau.xml.XmlSerializer#DEFAULT_NS_SQ_READABLE} - Same as
DEFAULT_SQ_READABLE but with namespaces enabled.
</ul>
<p>
In addition, DTO beans are provided that use the XML serializer
and parser for the following languages:
@@ -204,6 +202,7 @@
<ul>
<li>{@link org.apache.juneau.dto.atom} - ATOM beans.
<li>{@link org.apache.juneau.dto.cognos} - Cognos beans.
+ <li>{@link org.apache.juneau.dto.html5} - HTML5 beans.
</ul>
<p>
Refer to the package-level Javadocs for more information about
those formats.
@@ -260,12 +259,12 @@
<p>
The code above produces the following output:
</p>
- <p class='bcode'>
- <xt><object></xt>
- <xt><id></xt>1<xt></id></xt>
- <xt><name></xt>John Smith<xt></name></xt>
- <xt></object></xt>
- </p>
+ <p class='bcode'><xt>
+ <object>
+ <id><xv>1</xv></id>
+ <name><xv>John Smith</xv></name>
+ </object>
+ </xt></p>
<p>
The first thing you may notice is how the bean instance is
represented by the element <xt><object></xt>.<br>
When objects have no name associated with them, Juneau provides
a default generalized name that maps to the equivalent JSON data type.<br>
@@ -277,24 +276,418 @@
</ul>
<p>
The generalized name reflects the JSON-equivalent data type.<br>
- The full list of generalized element names are:
- </p>
- <ul>
- <li><xt><object></xt> - A bean or <code>Map</code>
element.
- <li><xt><array></xt> - An array or
<code>Collection</code> element.
- <li><xt><string></xt> - A string value.
- <li><xt><number></xt> - An int or float value.
- <li><xt><boolean></xt> - A boolean value.
- <li><xt><null/></xt> - A null value.
- </ul>
- <p>
Juneau produces JSON-equivalent XML, meaning any valid JSON
document can be losslessly converted into an XML equivalent.<br>
In fact, all of the Juneau serializers and parsers are built
upon this JSON-equivalency.
</p>
+
<!--
========================================================================================================
-->
+ <a id="Methodology"></a>
+ <h3 class='topic' onclick='toggle(this)'>2.1 - XML support
methodology</h3>
+ <div class='topic'>
+ <p>
+ The following examples show how different data types
are represented in XML.
+ They mirror how the data structures are represented in
JSON.
+ </p>
+ <h6 class='topic'>Simple types</h6>
+ <p>
+ The representation of loose (not a direct bean property
value) simple types are shown below:
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td>string</td>
+ <td class='code'><js>'foo'</js></td>
+ <td
class='code'><xt><string></xt>foo<xt></string></xt></td>
+ </tr>
+ <tr>
+ <td>boolean</td>
+ <td class='code'><jk>true</jk></td>
+ <td
class='code'><xt><boolean></xt>true<xt></boolean></xt></td>
+ </tr>
+ <tr>
+ <td>integer</td>
+ <td class='code'>123</td>
+ <td
class='code'><xt><number></xt>123<xt></number></xt></td>
+ </tr>
+ <tr>
+ <td>float</td>
+ <td class='code'>1.23</td>
+ <td
class='code'><xt><number></xt>1.23<xt></number></xt></td>
+ </tr>
+ <tr>
+ <td>null</td>
+ <td class='code'><jk>null</jk></td>
+ <td class='code'><xt><null/></xt></td>
+ </tr>
+ </table>
+ <h6 class='topic'>Maps</h6>
+ <p>
+ Loose maps and beans use the element
<xt><object></xt> for encapsulation.
+ </p>
+ <p>
+ <xa>_type</xa> attributes are added to bean properties
or map entries if the type cannot be inferred through reflection (e.g. an
<code>Object</code> or superclass/interface value type).
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ Map<String,String>
+ </td>
+ <td class='code'>
+ {
+ k1: <js>'v1'</js>
+ k2: <jk>null</jk>
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <k1><xv>v1</xv></k1>
+ <k2 <xa>_type</xa>=<xs>'null'</xs>/>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ Map<String,Number>
+ </td>
+ <td class='code'>
+ {
+ k1: 123,
+ k2: 1.23,
+ k3: <jk>null</jk>
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <k1><xv>123</xv></k1>
+ <k2><xv>1.23</xv></k2>
+ <k3 <xa>_type</xa>=<xs>'null'</xs>/>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ Map<String,Object>
+ </td>
+ <td class='code'>
+ {
+ k1: <js>'v1'</js>
+ k2: 123,
+ k3: 1.23,
+ k4: <jk>true</jk>,
+ k5: <jk>null</jk>
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <k1><xv>v1</xv></k1>
+ <k2
<xa>_type</xa>=<xs>'number'</xs>><xv>123</xv></k2>
+ <k3
<xa>_type</xa>=<xs>'number'</xs>><xv>1.23</xv></k3>
+ <k4
<xa>_type</xa>=<xs>'boolean'</xs>><xv>true</xv></k4>
+ <k5 <xa>_type</xa>=<xs>'null'</xs>/>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
+
+ <h6 class='topic'>Arrays</h6>
+ <p>
+ Loose collections and arrays use the element
<xt><array></xt> for encapsulation.
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ String[]
+ </td>
+ <td class='code'>
+ [
+ <js>'foo'</js>
+ <jk>null</jk>
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <string><xv>foo</xv></string>
+ <null/>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ Number[]
+ </td>
+ <td class='code'>
+ [
+ 123,
+ 1.23,
+ <jk>null</jk>
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <number><xv>123</xv></number>
+ <number><xv>1.23</xv></number>
+ <null/>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ Object[]
+ </td>
+ <td class='code'>
+ [
+ <js>'foo'</js>,
+ 123,
+ 1.23,
+ <jk>true</jk>,
+ <jk>null</jk>
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <string><xv>foo</xv></string>
+ <number><xv>123</xv></number>
+ <number><xv>1.23</xv></number>
+ <boolean><xv>true</xv></boolean>
+ <null/>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ String[][]
+ </td>
+ <td class='code'>
+ [
+ [<js>'foo'</js>, <jk>null</jk>],
+ <jk>null</jk>,
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <array>
+ <string><xv>foo</xv></string>
+ <null/>
+ </array>
+ <null/>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>int</jk>[]
+ </td>
+ <td class='code'>
+ [
+ 123
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <number><xv>123</xv></number>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>boolean</jk>[]
+ </td>
+ <td class='code'>
+ [
+ <jk>true</jk>
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <boolean><xv>true</xv></boolean>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ List<String>
+ </td>
+ <td class='code'>
+ [
+ <js>'foo'</js>
+ <jk>null</jk>
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <string><xv>foo</xv></string>
+ <null/>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ List<Number>
+ </td>
+ <td class='code'>
+ [
+ 123,
+ 1.23,
+ <jk>null</jk>
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <number><xv>123</xv></number>
+ <number><xv>1.23</xv></number>
+ <null/>
+ </array>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ List<Object>
+ </td>
+ <td class='code'>
+ [
+ <js>'foo'</js>,
+ 123,
+ 1.23,
+ <jk>true</jk>,
+ <jk>null</jk>
+ ]
+ </td>
+ <td class='code'><xt>
+ <array>
+ <string><xv>foo</xv></string>
+ <number><xv>123</xv></number>
+ <number><xv>1.23</xv></number>
+ <boolean><xv>true</xv></boolean>
+ <null/>
+ </array>
+ </xt></td>
+ </tr>
+ </table>
+
+ <h6 class='topic'>Beans</h6>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <jk>public</jk> String a;
+ <jk>public</jk> <jk>int</jk> b;
+ <jk>public</jk> Object c; <jc>// String value</jc>
+ <jk>public</jk> Object d; <jc>// Integer value</jc>
+ <jk>public</jk> MyBean2 e;
+ <jk>public</jk> String[] f;
+ <jk>public</jk> <jk>int</jk>[] g;
+ }
+ <jk>class</jk> MyBean2 {
+ String h;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>,
+ b: 123,
+ c: <js>'bar'</js>,
+ d: 456,
+ e: {
+ h: <js>'baz'</js>
+ }
+ f: [<js>'qux'</js>]
+ g: [789]
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a><xv>foo</xv></a>
+ <b><xv>123</xv></b>
+ <c><xv>bar</xv></c>
+ <d <xa>_type</xa>=<xs>'number'</xs>><xv>456</xv></d>
+ <e>
+ <h><xv>baz</xv></h>
+ </e>
+ <f>
+ <string><xv>qux</xv></string>
+ </f>
+ <g>
+ <number><xv>789</xv></number>
+ </g>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
+ <h6 class='topic'>Beans with Map properties</h6>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <jk>public</jk> Map<String,String> a;
+ <jk>public</jk> Map<String,Number> b;
+ <jk>public</jk> Map<String,Object> c;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: {
+ k1: <js>'foo'</js>
+ },
+ b: {
+ k2: 123
+ },
+ c: {
+ k3: <js>'bar'</js>,
+ k4: 456,
+ k5: <jk>true</jk>,
+ k6: <jk>null</jk>
+ }
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <k1><xv>foo</xv></k1>
+ </a>
+ <b>
+ <k2><xv>123</xv></k2>
+ </b>
+ <c>
+ <k3><xv>bar</xv></k3>
+ <k4
<xa>_type</xa>=<xs>'number'</xs>><xv>456</xv></k4>
+ <k5
<xa>_type</xa>=<xs>'boolean'</xs>><xv>true</xv></k5>
+ <k6 <xa>_type</xa>=<xs>'null'</xs>/>
+ </c>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
+ </div>
+
+
+ <!--
========================================================================================================
-->
<a id="XmlAnnotation"></a>
- <h3 class='topic' onclick='toggle(this)'>2.1 - @Xml annotations</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.2 - @Xml annotations</h3>
<div class='topic'>
<p>
Just because Juneau allows you to serialize ordinary
POJOs to XML doesn't mean you are limited to just JSON-equivalent XML.<br>
@@ -303,242 +696,986 @@
<!--
========================================================================================================
-->
<a id="XmlName"></a>
- <h4 class='topic' onclick='toggle(this)'>2.1.1 -
@Bean.typeName()</h4>
+ <h4 class='topic' onclick='toggle(this)'>2.2.1 -
@Bean.typeName()</h4>
<div class='topic'>
<p>
- The {@link
org.apache.juneau.annotation.Bean#typeName()} annotation can be used to
override the Juneau default name on unnamed objects.
+ The {@link
org.apache.juneau.annotation.Bean#typeName() @Bean.typeName()} annotation can
be used to override the Juneau default name on bean elements.
+ Types names serve two distinct purposes:
+ </p>
+ <ol>
+ <li>To override the element name.
+ <li>To serve as a class identifier so that the
bean class can be inferred during parsing if it
+ cannot automatically be inferred
through reflection.
+ </ol>
+ <h6 class='figure'>Example</h6>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(typeName=<js>"X"</js>)
+ <jk>class</jk> MyBean {
+ <jk>public</jk> String a;
+ <jk>public int</jk> b;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>,
+ b: 123
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a><xv>foo</xv></id>
+ <b><xv>123</xv></name>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <X>
+ <a><xv>foo</xv></id>
+ <b><xv>123</xv></name>
+ </X>
+ </xt></td>
+ </tr>
+ </table>
+ <p>
+ On bean properties, a <xa>_type</xa> attribute
will be added if a type name is present and the bean class cannot be inferred
through reflection.
+ </p>
+ <p>
+ In the following example, a type attribute is
used on property 'b' but not property 'a' since
+ 'b' is of type <code>Object</code> and
therefore the bean class cannot be inferred.
</p>
<h6 class='figure'>Example</h6>
- <p class='bcode'>
- <ja>@Bean</ja>(typeName=<js>"person"</js>)
- <jk>public class</jk> Person {
- ...
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Java</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <jk>public</jk> BeanX a = <jk>new</jk> BeanX();
+ <jk>public</jk> Object b = <jk>new</jk> BeanX();
+ }
+
+ <ja>@Bean</ja>(typeName=<js>"X"</js>)
+ <jk>class</jk> BeanX {
+ <jk>public</jk> String fx = <js>"foo"</js>;
+ }
+
+ </td>
+ <td class='code'><xt>
+<object>
+ <a>
+ <fx><xv>foo</xv></fx>
+ </a>
+ <b>
+ <fx><xv>foo</xv></fx>
+ </b>
+</object>
+ </xt></td>
+ <td class='code'><xt>
+<object>
+ <a>
+ <fx><xv>foo</xv></fx>
+ </a>
+ <b <xa>_type</xa>=<xs>'X'</xs>>
+ <fx><xv>foo</xv></fx>
+ </b>
+</object>
+ </xt></td>
+ </tr>
+ </table>
+ <p class='info'>
+ <code>string</code>, <code>number</code>,
<code>boolean</code>, <code>object</code>, <code>array</code>, and
<code>null</code> are reserved keywords that cannot be used as type names.
</p>
- <h6 class='figure'>Result</h6>
- <p class='bcode'>
- <xt><person></xt>
- <xt><id></xt>1<xt></id></xt>
- <xt><name></xt>John Smith<xt></name></xt>
- <xt></person></xt>
+ <p>
+ Beans with type names are often used in
conjunction with the {@link org.apache.juneau.annotation.Bean#beanDictionary()
@Bean.beanDictionary()} and
+ {@link
org.apache.juneau.annotation.BeanProperty#beanDictionary()
@BeanProperty.beanDictionary()} annotations so that the beans can be
+ resolved at parse time. These
annotations are not necessary during serialization, but are needed during
parsing in order to resolve the
+ bean types.
+ </p>
+ <p>
+ The following examples show how type names are
used under various circumstances.
+ Note that array dimensions are represented with
the caret <js>'^'</js> character.
+ For example, <js>"X^"</js> is a 1-dimensional
array, and <js>"X^^"</js> is a 2-dimensional array.
</p>
+ <p>
+ Pay special attention to when <xa>_type</xa>
attributes are and are not used.
+ </p>
+ <h6 class='figure'>Examples</h6>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Java</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(beanDictionary={BeanX.<jk>class</jk>})
+ <jk>class</jk> BeanWithArrayPropertiesWithTypeNames {
+ <jk>public</jk> BeanX[] b1 = <jk>new</jk> BeanX[]{
+ <jk>new</jk> BeanX()
+ };
+ <jk>public</jk> Object[] b2 = <jk>new</jk> BeanX[]{
+ <jk>new</jk> BeanX()
+ };
+ <jk>public</jk> Object[] b3 = <jk>new</jk> Object[]{
+ <jk>new</jk> BeanX()
+ };
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <b1>
+ <X>
+ <fx><xv>foo</xv></fx>
+ </X>
+ </b1>
+ <b2 <xa>_type</xa>=<xs>'X^'</xs>>
+ <X>
+ <fx><xv>foo</xv></fx>
+ </X>
+ </b2>
+ <b3>
+ <X>
+ <fx><xv>foo</xv></fx>
+ </X>
+ </b3>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(beanDictionary={BeanX.<jk>class</jk>})
+ <jk>class</jk> BeanWith2dArrayPropertiesWithTypeNames {
+ <jk>public</jk> BeanX[][] b1 = <jk>new</jk> BeanX[][]{{
+ <jk>new</jk> BeanX()
+ }};
+ <jk>public</jk> Object[][] b2 = <jk>new</jk> BeanX[][]{{
+ <jk>new</jk> BeanX()
+ }};
+ <jk>public</jk> Object[][] b3 = <jk>new</jk> Object[][]{{
+ <jk>new</jk> BeanX()
+ }};
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <b1>
+ <array>
+ <X>
+ <fx><xv>foo</xv></fx>
+ </X>
+ </array>
+ </b1>
+ <b2 <xa>_type</xa>=<xs>'X^^'</xs>>
+ <array>
+ <X>
+ <fx><xv>foo</xv></fx>
+ </X>
+ </array>
+ </b2>
+ <b3>
+ <array>
+ <X>
+ <fx><xv>foo</xv></fx>
+ </X>
+ </array>
+ </b3>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(beanDictionary={BeanX.<jk>class</jk>})
+ <jk>class</jk> BeanWithMapPropertiesWithTypeNames {
+ <jk>public</jk> Map<String,BeanX> b1 = <jk>new</jk>
HashMap<>() {{
+ put(<js>"k1"</js>, <jk>new</jk> BeanX());
+ }};
+ <jk>public</jk> Map<String,Object> b2 = <jk>new</jk>
HashMap<>() {{
+ put(<js>"k2"</js>, <jk>new</jk> BeanX());
+ }}
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <b1>
+ <k1>
+ <fx><xv>foo</xv></fx>
+ </k1>
+ </b1>
+ <b2>
+ <k2 <xa>_type</xa>=<xs>'X'</xs>>
+ <fx><xv>foo</xv></fx>
+ </k2>
+ </b2>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
+ <p>
+ Bean type names are also used for resolution
when abstract fields are used.
+ The following examples show how they are used
in a variety of circumstances.
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Java</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(beanDictionary={A.<jk>class</jk>})
+ <jk>class</jk> BeanWithAbstractFields {
+ <jk>public</jk> A a = <jk>new</jk> A();
+ <jk>public</jk> IA ia = <jk>new</jk> A();
+ <jk>public</jk> AA aa = <jk>new</jk> A();
+ <jk>public</jk> Object o = <jk>new</jk> A();
+ }
+
+ <jk>interface</jk> IA {}
+
+ <jk>abstract class</jk> AA <jk>implements</jk> IA {}
+
+ <ja>@Bean</ja>(typeName=<js>"A"</js>)
+ <jk>class</jk> A <jk>extends</jk> AA {
+ <jk>public</jk> String fa = <js>"foo"</js>;
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <fa><xv>foo</xv></fa>
+ </a>
+ <ia <xa>_type</xa>=<xs>'A'</xs>>
+ <fa><xv>foo</xv></fa>
+ </ia>
+ <aa <xa>_type</xa>=<xs>'A'</xs>>
+ <fa><xv>foo</xv></fa>
+ </aa>
+ <o <xa>_type</xa>=<xs>'A'</xs>>
+ <fa><xv>foo</xv></fa>
+ </o>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(beanDictionary={A.<jk>class</jk>})
+ <jk>class</jk> BeanWithAbstractArrayFields {
+ <jk>public</jk> A[] a = <jk>new</jk> A[]{<jk>new</jk> A()};
+ <jk>public</jk> IA[] ia1 = <jk>new</jk> A[]{<jk>new</jk> A()};
+ <jk>public</jk> IA[] ia2 = <jk>new</jk> IA[]{<jk>new</jk> A()};
+ <jk>public</jk> AA[] aa1 = <jk>new</jk> A[]{<jk>new</jk> A()};
+ <jk>public</jk> AA[] aa2 = <jk>new</jk> AA[]{<jk>new</jk> A()};
+ <jk>public</jk> Object[] o1 = <jk>new</jk> A[]{<jk>new</jk>
A()};
+ <jk>public</jk> Object[] o2 = <jk>new</jk>
Object[]{<jk>new</jk> A()};
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </a>
+ <ia1 <xa>_type</xa>=<xs>'A^'</xs>>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </ia1>
+ <ia2>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </ia2>
+ <aa1 <xa>_type</xa>=<xs>'A^'</xs>>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </aa1>
+ <aa2>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </aa2>
+ <o1 <xa>_type</xa>=<xs>'A^'</xs>>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </o1>
+ <o2>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </o2>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(beanDictionary={A.<jk>class</jk>})
+ <jk>class</jk> BeanWithAbstractMapFields {
+ <jk>public</jk> Map<String,A> a = <jk>new</jk>
HashMap<>() {{
+ put(<js>"k1"</js>, <jk>new</jk> A());
+ }};
+ <jk>public</jk> Map<String,AA> b = <jk>new</jk>
HashMap<>() {{
+ put(<js>"k2"</js>, <jk>new</jk> A());
+ }};
+ <jk>public</jk> Map<String,Object> c = <jk>new</jk>
HashMap<>() {{
+ put(<js>"k3"</js>, <jk>new</jk> A());
+ }};
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <k1>
+ <fa><xv>foo</xv></fa>
+ </k1>
+ </a>
+ <b>
+ <k2 <xa>_type</xa>=<xs>'A'</xs>>
+ <fa><xv>foo</xv></fa>
+ </k2>
+ </b>
+ <c>
+ <k3 <xa>_type</xa>=<xs>'A'</xs>>
+ <fa><xv>foo</xv></fa>
+ </k3>
+ </c>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(beanDictionary={A.<jk>class</jk>})
+ <jk>class</jk> BeanWithAbstractMapArrayFields {
+ <jk>public</jk> Map<String,A[]> a = <jk>new</jk>
LinkedHashMap<>() {{
+ put(<js>"a1"</js>, <jk>new</jk> A[]{<jk>new</jk> A()});
+ }};
+ <jk>public</jk> Map<String,IA[]> ia = <jk>new</jk>
LinkedHashMap<>() {{
+ put(<js>"ia1"</js>, <jk>new</jk> A[]{<jk>new</jk> A()});
+ put(<js>"ia2"</js>, <jk>new</jk> IA[]{<jk>new</jk>
A()});
+ }};
+ <jk>public</jk> Map<String,AA[]> aa = <jk>new</jk>
LinkedHashMap<>() {{
+ put(<js>"aa1"</js>, <jk>new</jk> A[]{<jk>new</jk> A()});
+ put(<js>"aa2"</js>, <jk>new</jk> AA[]{<jk>new</jk>
A()});
+ }};
+ <jk>public</jk> Map<String,Object[]> o =
<jk>new</jk>LinkedHashMap<>() {{
+ put(<js>"o1"</js>, <jk>new</jk> A[]{<jk>new</jk> A()});
+ put(<js>"o2"</js>, <jk>new</jk> AA[]{<jk>new</jk> A()});
+ }};
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <a1>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </a1>
+ </a>
+ <ia>
+ <ia1 <xa>_type</xa>=<xs>'A^'</xs>>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </ia1>
+ <ia2>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </ia2>
+ </ia>
+ <aa>
+ <aa1 <xa>_type</xa>=<xs>'A^'</xs>>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </aa1>
+ <aa2>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </aa2>
+ </aa>
+ <o>
+ <o1 <xa>_type</xa>=<xs>'A^'</xs>>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </o1>
+ <o2>
+ <A>
+ <fa><xv>foo</xv></fa>
+ </A>
+ </o2>
+ </o>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
+ <p>
+ On a side note, characters that cannot be
represented in XML 1.0 are encoded using a simple encoding.
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Java</th>
+ <th>XML</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> BeanWithSpecialCharacters {
+ <jk>public</jk> String a = <js>"\n\b\f\t"</js>;
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a><xv>_x000A__x0008__x000C__x0009_</xv></a>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Bean</ja>(typeName=<js>"$#!"</js>)
+ <jk>class</jk> BeanWithNamesWithSpecialCharacters {
+ <ja>@BeanProperty</ja>(name=<js>"*()"</js>)
+ <jk>public</jk> String a = <js>"\n\b\f\t"</js>;
+ }
+ </td>
+ <td class='code'><xt>
+ <_x0024__x0023__x0021_>
+
<_x002A__x0028__x0029_><xv>_x000A__x0008__x000C__x0009_</xv></_x002A__x0028__x0029_>
+ </_x0024__x0023__x0021_>
+ </xt></td>
+ </tr>
+ </table>
</div>
<!--
========================================================================================================
-->
<a id="XmlChildName"></a>
- <h4 class='topic' onclick='toggle(this)'>2.1.2 -
@Xml.childName()</h4>
+ <h4 class='topic' onclick='toggle(this)'>2.2.2 -
@Xml.childName()</h4>
<div class='topic'>
<p>
- The {@link
org.apache.juneau.xml.annotation.Xml#childName()} annotation can be used to
specify the name of XML
+ The {@link
org.apache.juneau.xml.annotation.Xml#childName() @Xml.childName()} annotation
can be used to specify the name of XML
child elements for bean properties of
type collection or array.
</p>
<h6 class='figure'>Example</h6>
- <p class='bcode'>
- <jk>public class</jk> MyBean {
- <ja>@Xml</ja>(childName=<js>"child"</js>}
- <jk>public</jk> String[] <jf>children</jf> =
{<js>"foo"</js>,<js>"bar"</js>};
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(childName=<js>"X"</js>)
+ <jk>public</jk> String[] a;
+ <ja>@Xml</ja>(childName=<js>"Y"</js>)
+ <jk>public</jk> int[] b;
}
- </p>
- <h6 class='figure'>Results without annotation</h6>
- <p class='bcode'>
- <xt><object></xt>
- <xt><children></xt>
- <xt><string></xt>foo<xt></string></xt>
- <xt><string></xt>bar<xt></string></xt>
- <xt></children></xt>
- <xt></object></xt>
- </p>
- <h6 class='figure'>Results with annotation</h6>
- <p class='bcode'>
- <xt><object></xt>
- <xt><children></xt>
- <xt><child></xt>foo<xt></child></xt>
- <xt><child></xt>bar<xt></child></xt>
- <xt></children></xt>
- <xt></object></xt>
- </p>
+ </td>
+ <td class='code'>
+ {
+ a: [<js>'foo'</js>,<js>'bar'</js>],
+ b: [123,456]
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <string><xv>foo</xv></string>
+ <string><xv>bar</xv></string>
+ </a>
+ <b>
+ <number><xv>123</xv></number>
+ <number><xv>456</xv></number>
+ </b>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <X><xv>foo</xv></X>
+ <X><xv>bar</xv></X>
+ </a>
+ <b>
+ <Y><xv>123</xv></Y>
+ <Y><xv>456</xv></Y>
+ </b>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(childName=<js>"child"</js>)
+ <jk>public</jk> int[] a;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: [123,456]
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <string><xv>foo</xv></string>
+ <string><xv>bar</xv></string>
+ </a>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <child><xv>foo</xv></child>
+ <child><xv>bar</xv></child>
+ </a>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
</div>
<!--
========================================================================================================
-->
<a id="XmlFormat"></a>
- <h4 class='topic' onclick='toggle(this)'>2.1.3 -
@Xml.format()</h4>
+ <h4 class='topic' onclick='toggle(this)'>2.2.3 -
@Xml.format()</h4>
<div class='topic'>
<p>
- The {@link
org.apache.juneau.xml.annotation.Xml#format()} annotation can be used to tweak
the XML format of a POJO.<br>
- The value is set to an enum value of type
{@link org.apache.juneau.xml.annotation.XmlFormat}.<br>
- This annotation can be applied to both classes
and bean properties.
+ The {@link
org.apache.juneau.xml.annotation.Xml#format() @Xml.format()} annotation can be
used to tweak the XML format of a POJO.
+ <br>The value is set to an enum value of type
{@link org.apache.juneau.xml.annotation.XmlFormat}.
+ <br>This annotation can be applied to both
classes and bean properties.
+ </p>
+ <p>
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#ATTR} format can be applied to bean
properties to serialize
+ them as XML attributes instead of elements.
+ <br>Note that this only supports properties of
simple types (e.g. strings, numbers, booleans).
</p>
- <h6 class='figure'>Possible values</h6>
- <ul class='spaced-list'>
- <li>{@link
org.apache.juneau.xml.annotation.XmlFormat#NORMAL} - Normal formatting
(default).
- <li>{@link
org.apache.juneau.xml.annotation.XmlFormat#ATTR} - Render as an XML attribute
when it would normally be rendered as an element.<br>
- Can be applied to classes and
properties that serialize to simple types (e.g. <code>String</code>,
<code>Number</code>).
- <li>{@link
org.apache.juneau.xml.annotation.XmlFormat#ELEMENT} - Render as an XML element
when it would normally be rendered as an attribute.<br>
- Can be applied to URL and ID bean
properties that would normally be rendered as attributes.
- <li>{@link
org.apache.juneau.xml.annotation.XmlFormat#COLLAPSED} - Prevents collections
and arrays from being enclosed in an <xt><array></xt> (or named
equivalent) element.<br>
- Can be applied to properties of type
collection or array, or to classes that subclass from <code>Collection</code>.
- <li>{@link
org.apache.juneau.xml.annotation.XmlFormat#CONTENT} - Render property value
directly as content of element.<br>
- Can be used in combination with {@link
org.apache.juneau.xml.annotation.Xml#contentHandler()} to produce something
other than plain text, such as embedded XML.
- </ul>
<h6 class='figure'>Example</h6>
- <p class='bcode'>
- <jk>public class</jk> MyBean {
-
- <jc>// Normally, bean properties would be rendered as child
elements of the bean element.</jc>
- <jc>// Override so that it's rendered as a "f1='123'" attribute
on the bean element instead.</jc>
- <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>}
- <jk>public int</jk> f1 = 123;
-
- <jc>// Normally, bean URL properties would be rendered as XML
attributes on the bean element.</jc>
- <jc>// Override so that it's rendered as an
<href>http://foo</href> child element instead.</jc>
- <ja>@BeanProperty</ja>(uri=<jk>true</jk>)
- <ja>@Xml</ja>(format=XmlFormat.<jsf>ELEMENT</jsf>}
- <jk>public</jk> URL <jf>href</jf> = <jk>new</jk>
URL(<js>"http://foo"</js>);
-
- <jc>// Normally, collection properties would be grouped under a
single <children> child element on the bean element.</jc>
- <jc>// Override so that entries are directly children of the
bean element with each entry having an element name of <child>.</jc>
- <ja>@Xml</ja>(format=XmlFormat.<jsf>COLLAPSED</jsf>,
childName=<js>"child"</js>}
- <jk>public</jk> String[] <jf>children</jf> =
<js>"foo"</js>,<js>"bar"</js>};
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>)
+ <jk>public</jk> String a;
}
- </p>
- <h6 class='figure'>Results without annotation</h6>
- <p class='bcode'>
- <xt><object</xt> <xa>href</xa>=<js>'http://foo'</js><xt>></xt>
- <xt><f1></xt>123<xt></f1></xt>
- <xt><children></xt>
- <xt><string></xt>foo<xt></string></xt>
- <xt><string></xt>bar<xt></string></xt>
- <xt></children></xt>
- <xt></object></xt>
- </p>
- <h6 class='figure'>Results with annotation</h6>
- <p class='bcode'>
- <xt><object</xt> <xa>f1</xa>=<js>'123'</js><xt>></xt>
- <xt><href></xt>http://foo<xt></href></xt>
- <xt><child></xt>foo<xt></child></xt>
- <xt><child></xt>bar<xt></child></xt>
- <xt></object></xt>
- </p>
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a><xv>foo</xv></a>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object <xa>a</xa>=<xs>'foo'</xs>/>
+ </xt></td>
+ </tr>
+ </table>
<p>
- The {@link
org.apache.juneau.xml.annotation.XmlFormat#CONTENT} annotation can be used to
serialize a bean
- straight to text without any child
elements.
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#ATTRS} format can be applied to bean
classes to force all bean properties
+ to be serialized as XML attributes instead of
child elements.
</p>
<h6 class='figure'>Example</h6>
- <p class='bcode'>
- <ja>@Bean</ja>(typeName=<js>"MyBean"</js>)
- <jk>public class</jk> MyBean {
-
- <ja>@Xml</ja>(format=XmlFormat.<jsf>CONTENT</jsf>)
- <jk>public</jk> String beanContents = <js>"This is my
bean"</js>;
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTRS</jsf>)
+ <jk>class</jk> MyBean {
+ <jk>public</jk> String a;
+ <jk>public int</jk> b;
}
- </p>
- <h6 class='figure'>Results</h6>
- <p class='bcode'>
- <xt><MyBean></xt>
- This is my bean
- <xt></MyBean></xt>
- </p>
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>,
+ b: 123
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a><xv>foo</xv></a>
+ <b><xv>123</xv></b>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object <xa>a</xa>=<xs>'foo'</xs> <xa>b</xa>=<xs>'123'</xs>/>
+ </xt></td>
+ </tr>
+ </table>
<p>
- There are some restrictions when using the
<jsf>CONTENT</jsf> format:
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#ELEMENT} format can be applied to
bean properties to override
+ the {@link
org.apache.juneau.xml.annotation.XmlFormat#ATTRS} format applied on the bean
class.
</p>
- <ul class='spaced-list'>
- <li>A bean class can only have one property
denoted with <jsf>CONTENT</jsf> format.
- <li>A bean class cannot have any other
properties that would serialize to an element (attributes are okay).
- </ul>
+ <h6 class='figure'>Example</h6>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTRS</jsf>)
+ <jk>class</jk> MyBean {
+ <jk>public</jk> String a;
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ELEMENT</jsf>)
+ <jk>public int</jk> b;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>,
+ b: 123
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a><xv>foo</xv></a>
+ <b><xv>123</xv></b>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object <xa>a</xa>=<xs>'foo'</xs></xs>>
+ <b><xv>123</xv></b>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
<p>
- The class type on the property can be anything
that serializes to a simple value, like a <code>String</code> or
<code>Number</code>.<br>
- Note that transforms can usually be used to
convert more complex class types to simple types.
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#ATTRS} format can be applied to a
single bean property
+ of type <code>Map<String,Object></code>
to denote arbitrary XML attribute values on the element.
+ <br>These can be mixed with other {@link
org.apache.juneau.xml.annotation.XmlFormat#ATTR} annotated properties, but
+ there must not be an overlap in bean property
names and map keys.
</p>
- </div>
-
-
- <!--
========================================================================================================
-->
- <a id="XmlContentHandler"></a>
- <h4 class='topic' onclick='toggle(this)'>2.1.4 -
@Xml.contentHandler()</h4>
- <div class='topic'>
+ <h6 class='figure'>Example</h6>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTRS</jsf>)
+ <jk>public</jk> Map<String,Object> a;
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>)
+ <jk>public int</jk> b;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: {
+ k1: <js>'foo'</js>,
+ k2: 123,
+ },
+ b: 456
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <k1><xv>foo</xv></k1>
+ <k2
<xa>_type</xa>=<xs>'number'</xs>><xv>123</xv></k2>
+ </a>
+ <b><xv>456</xv></b>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object <xa>k1</xa>=<xs>'foo'</xs> <xa>k2</xa>=<xs>'123'</xs>
<xa>b</xa>=<xs>'456'</xs>/>
+ </xt></td>
+ </tr>
+ </table>
<p>
- The {@link
org.apache.juneau.xml.annotation.Xml#contentHandler()} annotation is an
advanced feature that allows you to
- define your own code for serializing
and parsing the contents of a serialized bean.
- </p>
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#COLLAPSED} format can be applied to
bean properties
+ of type array/Collection.
+ <br>This causes the child objects to be
serialized directly inside the bean element.
+ <br>This format must be used in conjunction
with {@link org.apache.juneau.xml.annotation.Xml#childName()}
+ to differentiate which collection the values
came from if you plan on parsing the output back into beans.
+ <br>Note that child names must not conflict
with other property names.
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotation</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+
<ja>@Xml</ja>(childName=<js>"A"</js>,format=XmlFormat.<jsf>COLLAPSED</jsf>)
+ <jk>public</jk> String[] a;
+
<ja>@Xml</ja>(childName=<js>"B"</js>,format=XmlFormat.<jsf>COLLAPSED</jsf>)
+ <jk>public int</jk>[] b;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: [<js>'foo'</js>,<js>'bar'</js>],
+ b: [123,456]
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <string><xv>foo</xv></string>
+ <string><xv>bar</xv></string>
+ </a>
+ <b>
+ <number><xv>123</xv></number>
+ <number><xv>456</xv></number>
+ </b>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object>
+ <A><xv>foo</xv></A>
+ <A><xv>bar</xv></A>
+ <B><xv>123</xv></B>
+ <B><xv>456</xv></B>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
<p>
- For example, the ATOM specification allows for
the media type of <code>Text</code> elements to be specified via a
<xa>type</xa> attribute:
- </p>
- <p class='bcode'>
- <xt><feed></xt>
- <xt><entry></xt>
- <xt><title</xt>
<xa>type</xa>=<xs>'text'</xs>></xt>
- A &lt;em&gt;really&lt;/em&gt;
great title
- <xt></title></xt>
- <xt><content</xt>
<xa>type</xa>=<xs>'xhtml'</xs>></xt>
- <xt><div</xt>
<xa>xmlns</xa>=<xs>"http://www.w3.org/1999/xhtml"</xs><xt>></xt><xt><p></xt><xt><i></xt>This
is the contents of this
entry.<xt></i></xt><xt></p></xt><xt></div></xt>
- <xt></content></xt>
- <xt></entry></xt>
- <xt></feed></xt>
- </p>
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#ELEMENTS} format can be applied to a
single bean property
+ of either a simple type or array/Collection.
+ <br>It allows free-form child elements to be
formed.
+ <br>All other properties on the bean MUST be
serialized as attributes.
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>With annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>)
+ <jk>public</jk> String a;
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ELEMENTS</jsf>)
+ <jk>public</jk> String b;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>,
+ b: <js>'bar'</js>
+ }
+ </td>
+ <td class='code'><xt>
+ <object <xa>a</xa>=<xs>'foo'</xs>>
+ <string><xv>bar</xv></string>
+ </object>
+ </xt></td>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>)
+ <jk>public</jk> String a;
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ELEMENTS</jsf>)
+ <jk>public</jk> Object[] b;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>,
+ b: [
+ <js>'bar'</js>,
+ <js>'baz'</js>,
+ 123,
+ <jk>true</jk>,
+ <jk>null</jk>
+ ]
+ }
+ </td>
+ <td class='code'><xt>
+ <object <xa>a</xa>=<xs>'foo'</xs>>
+ <string><xv>bar</xv></string>
+ <string><xv>baz</xv></string>
+ <number><xv>123</xv></number>
+ <boolean><xv>true</xv></boolean>
+ <null/>
+ </object>
+ </xt></td>
+ </tr>
+ </table>
<p>
- To accomplish this, the {@link
org.apache.juneau.dto.atom.Text} class uses a content handler that serializes
and parses the value by inspecting the <xa>type</xa> value and then handling
the content accordingly:
- </p>
- <p class='bcode'>
- <jk>public class</jk> Text <jk>extends</jk> Common {
-
- <jk>private</jk> String <jf>type</jf>;
- <jk>private</jk> String <jf>text</jf>;
-
- <ja>@Xml</ja>(format=<jsf>ATTR</jsf>)
- <jk>public</jk> String getType() {
- <jk>return</jk> <jf>type</jf>;
- }
-
- <jk>public</jk> Text setType(String type) {
- <jk>this</jk>.<jf>type</jf> = type;
- <jk>return this</jk>;
- }
-
- <ja>@Xml</ja>(format=<jsf>CONTENT</jsf>,
contentHandler=TextContentHandler.<jk>class</jk>)
- <jk>public</jk> String getText() {
- <jk>return</jk> text;
- }
-
- <jk>public</jk> Text setText(String text) {
- <jk>this</jk>.<jf>text</jf> = text;
- <jk>return this</jk>;
- }
-
- <jc>// Converts the text to and from the appropriate media
type.</jc>
- <jk>public class</jk> TextContentHandler <jk>implements</jk>
XmlContentHandler<Text> {
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#MIXED} format is similar to {@link
org.apache.juneau.xml.annotation.XmlFormat#ELEMENTS}
+ except elements names on primitive types
(string/number/boolean/null) are stripped from the output.
+ This format particularly useful when combined
with bean dictionaries to produce mixed content.
+ <br>The bean dictionary isn't used during
serialization, but it is needed during parsing to resolve bean types.
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotations</th>
+ <th>With annotations</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>MIXED</jsf>)
+ <ja>@BeanProperty</ja>(beanDictionary={MyBeanX.<jk>class</jk>,
MyBeanY.<jk>class</jk>})
+ <jk>public</jk> Object[] a;
+ }
- <ja>@Override</ja>
- <jk>public void</jk> parse(XMLStreamReader r, Text
text) <jk>throws</jk> Exception {
- String type = text.<jf>type</jf>;
- <jk>if</jk> (type != <jk>null</jk> &&
type.equals(<js>"xhtml"</js>))
- text.<jf>text</jf> =
<jsm>decode</jsm>(readXmlContents(r).trim());
- <jk>else</jk>
- text.<jf>text</jf> =
<jsm>decode</jsm>(r.getElementText().trim());
- }
+ <ja>@Bean</ja>(typeName=<js>"X"</js>)
+ <jk>class</jk> MyBeanX {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>)
+ <jk>public</jk> String b;
+ }
- <ja>@Override</ja>
- <jk>public void</jk> serialize(XmlSerializerWriter w,
Text text) <jk>throws</jk> Exception {
- String type = text.<jf>type</jf>;
- String content = text.<jf>text</jf>;
- <jk>if</jk> (type != <jk>null</jk> &&
type.equals(<js>"xhtml"</js>))
- w.encodeTextInvalidChars(content);
- <jk>else</jk>
- w.encodeText(content);
- }
- }
+ <ja>@Bean</ja>(typeName=<js>"Y"</js>)
+ <jk>class</jk> MyBeanY {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>)
+ <jk>public</jk> String c;
}
- </p>
+ </td>
+ <td class='code'>
+ {
+ a: [
+ <js>'foo'</js>,
+ { _type:<js>'X'</js>, b:<js>'bar'</js> }
+ <js>'baz'</js>,
+ { _type:<js>'Y'</js>, b:<js>'qux'</js> },
+ <js>'quux'</js>
+ ]
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a>
+ <string><xv>foo</xv></string>
+ <object>
+ <b><xv>bar</xv></b>
+ </object>
+ <string><xv>baz</xv></string>
+ <object>
+ <b><xv>qux</xv></b>
+ </object>
+ <string><xv>quux</xv></string>
+ </a>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object><xv>foo</xv><X
<xa>b</xa>=<xs>'bar'</xs>/><xv>baz</xv><Y
<xa>c</xa>=<xs>'qux'</xs>/><xv>quux</xv></object>
+ </xt></td>
+ </tr>
+ </table>
<p>
- Refer to {@link
org.apache.juneau.xml.XmlContentHandler} for more information.
+ It should be noted that when using
<jsf>MIXED</jsf>, you are not guaranteed to parse back the exact same content
+ since side-by-side strings in the content will
end up concatenated when parsed.
</p>
+ <p>
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#TEXT} format is similar to {@link
org.apache.juneau.xml.annotation.XmlFormat#MIXED}
+ except it's meant for solitary objects that get
serialized as simple child text nodes.
+ <br>Any object that can be serialize to a
<code>String</code> can be used.
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>Without annotations</th>
+ <th>With annotations</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>TEXT</jsf>)
+ <jk>public</jk> String a;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: <js>'foo'</js>
+ }
+ </td>
+ <td class='code'><xt>
+ <object>
+ <a><xv>foo</xv></a>
+ </object>
+ </xt></td>
+ <td class='code'><xt>
+ <object><xv>foo</xv></object>
+ </xt></td>
+ </tr>
+ </table>
+ <p>
+ The {@link
org.apache.juneau.xml.annotation.XmlFormat#XMLTEXT} format is similar to {@link
org.apache.juneau.xml.annotation.XmlFormat#TEXT}
+ except it's meant for strings containing XML
that should be serialized as-is to the document.
+ <br>Any object that can be serialize to a
<code>String</code> can be used.
+ <br>During parsing, the element content gets
parsed with the rest of the document and then re-serialized to XML before being
set as the
+ property value. This process may not be
perfect (e.g. double quotes may be replaced by single quotes, etc...).
+ </p>
+ <table class='styled' style='width:auto'>
+ <tr>
+ <th>Data type</th>
+ <th>JSON example</th>
+ <th>With TEXT annotation</th>
+ <th>With XMLTEXT annotation</th>
+ </tr>
+ <tr>
+ <td class='code'>
+ <jk>class</jk> MyBean {
+ <ja>@Xml</ja>(format=XmlFormat.<jsf>XMLTEXT</jsf>)
+ <jk>public</jk> String a;
+ }
+ </td>
+ <td class='code'>
+ {
+ a: <js>'Some <b>XML</b> text'</js>
+ }
+ </td>
+ <td class='code'><xt>
+ <object><xv>Some &lt;b&gt;XML&lt;/b&gt;
text</xv></object>
+ </xt></td>
+ <td class='code'><xt>
+ <object><xv>Some <xt><b></xt>XML<xt></b></xt>
text</xv></object>
+ </xt></td>
+ </tr>
+ </table>
</div>
</div>
<!--
========================================================================================================
-->
<a id="Namespaces"></a>
- <h3 class='topic' onclick='toggle(this)'>2.2 - Namespaces</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.3 - Namespaces</h3>
<div class='topic'>
<p>
Let's go back to the example of our original
<code>Person</code> bean class:
@@ -564,7 +1701,9 @@
</p>
<p class='bcode'>
<jc>// Create a new serializer with readable output, this time with
namespaces enabled.</jc>
+ <jc>// Note that this is identical to
XmlSerializer.DEFAULT_NS_SQ_READABLE.</jc>
XmlSerializer s = <jk>new</jk> XmlSerializer()
+
.setProperty(XmlSerializerContext.<jsf>XML_enableNamespaces</jsf>,
<jk>true</jk>)
.setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>,
<jk>true</jk>)
.setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>,
<js>'\''</js>);
@@ -579,8 +1718,7 @@
</p>
<p class='bcode'>
<xt><object</xt>
-
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs><xt>></xt>
+
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs><xt>></xt>
<xt><id></xt>1<xt></id></xt>
<xt><name></xt>John Smith<xt></name></xt>
<xt></object></xt>
@@ -588,7 +1726,6 @@
<p>
This isn't too exciting yet since we haven't specified
any namespaces yet.<br>
Therefore, everything is defined under the default
<code>Juneau</code> namespace.<br>
- The <code>xsi</code> namespace is always present and is
used to mark null property values with
<code><xa>nil</xa>=<xs>'true'</xs></code>.
</p>
<p>
Namespaces can be defined at the following levels:
@@ -644,8 +1781,7 @@
<p class='bcode'>
<xt><per:person</xt>
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
-
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs><xt>></xt>
+
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs><xt>></xt>
<xt><per:id></xt>1<xt></per:id></xt>
<xt><per:name></xt>John Smith<xt></per:name></xt>
<xt></per:person></xt>
@@ -658,6 +1794,7 @@
XmlSerializer s = <jk>new</jk> XmlSerializer()
.setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>,
<jk>true</jk>)
.setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>,
<js>'\''</js>)
+
.setProperty(XmlSerializerContext.<jsf>XML_enableNamespaces</jsf>,
<jk>true</jk>)
.setProperty(XmlSerializerContext.<jsf>XML_defaultNamespaceUri</jsf>,
<js>"http://www.apache.org/person/"</js>);
</p>
<p>
@@ -666,8 +1803,7 @@
<p class='bcode'>
<xt><person</xt>
<xa>xmlns</xa>=<xs>'http://www.apache.org/person/'</xs>
-
<xa>xmlns:juneau</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs><xt>></xt>
+
<xa>xmlns:juneau</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs><xt>></xt>
<xt><id></xt>1<xt></id></xt>
<xt><name></xt>John Smith<xt></name></xt>
<xt></person></xt>
@@ -676,7 +1812,7 @@
<!--
========================================================================================================
-->
<a id="AutoDetectNamespaces"></a>
- <h4 class='topic' onclick='toggle(this)'>2.2.1 - Auto-detection
of namespaces</h4>
+ <h4 class='topic' onclick='toggle(this)'>2.3.1 - Auto-detection
of namespaces</h4>
<div class='topic'>
<p>
One important property on the XML serializer
class is {@link
org.apache.juneau.xml.XmlSerializerContext#XML_autoDetectNamespaces
XML_autoDetectNamespaces}.<br>
@@ -701,7 +1837,7 @@
<!--
========================================================================================================
-->
<a id="BeanAnnotations"></a>
- <h3 class='topic' onclick='toggle(this)'>2.3 - @Bean and @BeanProperty
annotations</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.4 - @Bean and @BeanProperty
annotations</h3>
<div class='topic'>
<p>
The {@link org.apache.juneau.annotation.Bean @Bean} and
{@link org.apache.juneau.annotation.BeanProperty @BeanProperty} annotations
@@ -751,7 +1887,6 @@
<xt><per:person</xt>
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
<xt><per:id></xt>1<xt></per:id></xt>
<xt><per:name></xt>John Smith<xt></per:name></xt>
@@ -777,7 +1912,6 @@
<xt><per:person</xt>
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
<xt><per:id></xt>1<xt></per:id></xt>
<xt><per:name></xt>John Smith<xt></per:name></xt>
@@ -790,7 +1924,7 @@
<!--
========================================================================================================
-->
<a id="Collections"></a>
- <h3 class='topic' onclick='toggle(this)'>2.4 - Collections</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.5 - Collections</h3>
<div class='topic'>
<p>
In our example, let's add a list-of-beans property to
our sample class:
@@ -851,7 +1985,6 @@
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
<xa>xmlns:addr</xa>=<xs>'http://www.apache.org/address/'</xs>
<xa>xmlns:mail</xa>=<xs>'http://www.apache.org/mail/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
<xt><per:id></xt>1<xt></per:id></xt>
<xt><per:name></xt>John Smith<xt></per:name></xt>
@@ -875,14 +2008,14 @@
<!--
========================================================================================================
-->
<a id="XmlSchemaSupport"></a>
- <h3 class='topic' onclick='toggle(this)'>2.5 - XML-Schema support</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.6 - XML-Schema support</h3>
<div class='topic'>
<p>
Juneau provides the {@link
org.apache.juneau.xml.XmlSchemaSerializer} class for generating XML-Schema
documents
that describe the output generated by the
{@link org.apache.juneau.xml.XmlSerializer} class.<br>
This class shares the same properties as
<code>XmlSerializer</code>.<br>
Since the XML output differs based on settings on the
XML serializer class, the XML-Schema serializer
- class must have the same property values as the
XML serializer class it's describing.<br>
+ class must have the same property values as the
XML serializer class it's descriqux.<br>
To help facilitate creating an XML Schema serializer
with the same properties as the corresponding
XML serializer, the {@link
org.apache.juneau.xml.XmlSerializer#getSchemaSerializer()} method
has been added.
@@ -971,7 +2104,6 @@
<p class='bcode'>
<xt><person</xt>
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
<xt><id></xt>1<xt></id></xt>
<xt><name></xt>John Smith<xt></name></xt>
@@ -997,16 +2129,16 @@
<xa>targetNamespace</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
<xa>elementFormDefault</xa>=<xs>'qualified'</xs>
<xa>xmlns:juneau</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs><xt>></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'person'</xs>
<xa>type</xa>=<xs>'juneau:org.apache.juneau.samples.addressbook.Person'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'person'</xs>
<xa>_type</xa>=<xs>'juneau:org.apache.juneau.samples.addressbook.Person'</xs><xt>/></xt>
<xt><complexType</xt>
<xa>name</xa>=<xs>'org.apache.juneau.samples.addressbook.Person'</xs><xt>></xt>
<xt><sequence></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'id'</xs> <xa>type</xa>=<xs>'integer'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'name'</xs> <xa>type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'addressBookUri'</xs> <xa>type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'birthDate'</xs>
<xa>type</xa>=<xs>'juneau:java.util.Calendar'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'addresses'</xs>
<xa>type</xa>=<xs>'juneau:java.util.LinkedList_x003C_org.apache.juneau.samples.addressbook.Address_x003E_'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'id'</xs> <xa>_type</xa>=<xs>'integer'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'name'</xs> <xa>_type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'addressBookUri'</xs> <xa>_type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'birthDate'</xs>
<xa>_type</xa>=<xs>'juneau:java.util.Calendar'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'addresses'</xs>
<xa>_type</xa>=<xs>'juneau:java.util.LinkedList_x003C_org.apache.juneau.samples.addressbook.Address_x003E_'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
<xt></sequence></xt>
- <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>type</xa>=<xs>'string'</xs><xt>/></xt>
+ <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>_type</xa>=<xs>'string'</xs><xt>/></xt>
<xt></complexType></xt>
<xt><complexType</xt>
<xa>name</xa>=<xs>'java.util.Calendar'</xs><xt>></xt>
<xt><sequence></xt>
@@ -1016,22 +2148,22 @@
<xt><complexType</xt>
<xa>name</xa>=<xs>'java.util.LinkedList_x003C_org.apache.juneau.samples.addressbook.Address_x003E_'</xs><xt>></xt>
<xt><sequence></xt>
<xt><choice</xt>
<xa>minOccurs</xa>=<xs>'0'</xs>
<xa>maxOccurs</xa>=<xs>'unbounded'</xs><xt>></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'address'</xs>
<xa>type</xa>=<xs>'juneau:org.apache.juneau.samples.addressbook.Address'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'null'</xs> <xa>type</xa>=<xs>'string'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'address'</xs>
<xa>_type</xa>=<xs>'juneau:org.apache.juneau.samples.addressbook.Address'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'null'</xs> <xa>_type</xa>=<xs>'string'</xs><xt>/></xt>
<xt></choice></xt>
<xt></sequence></xt>
<xt></complexType></xt>
<xt><complexType</xt>
<xa>name</xa>=<xs>'org.apache.juneau.samples.addressbook.Address'</xs><xt>></xt>
<xt><sequence></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'personUri'</xs> <xa>type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'id'</xs> <xa>type</xa>=<xs>'integer'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'street'</xs> <xa>type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'city'</xs> <xa>type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'state'</xs> <xa>type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'zip'</xs> <xa>type</xa>=<xs>'integer'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'isCurrent'</xs> <xa>type</xa>=<xs>'boolean'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'personUri'</xs> <xa>_type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'id'</xs> <xa>_type</xa>=<xs>'integer'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'street'</xs> <xa>_type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'city'</xs> <xa>_type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'state'</xs> <xa>_type</xa>=<xs>'string'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'zip'</xs> <xa>_type</xa>=<xs>'integer'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'isCurrent'</xs> <xa>_type</xa>=<xs>'boolean'</xs>
<xa>minOccurs</xa>=<xs>'0'</xs><xt>/></xt>
<xt></sequence></xt>
- <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>type</xa>=<xs>'string'</xs><xt>/></xt>
+ <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>_type</xa>=<xs>'string'</xs><xt>/></xt>
<xt></complexType></xt>
<xt></schema></xt>
</p>
@@ -1061,7 +2193,6 @@
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
<xa>xmlns:addr</xa>=<xs>'http://www.apache.org/address/'</xs>
<xa>xmlns:mail</xa>=<xs>'http://www.apache.org/mail/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
<xt><per:id></xt>1<xt></per:id></xt>
<xt><per:name></xt>John Smith<xt></per:name></xt>
@@ -1119,8 +2250,8 @@
<xt><complexType</xt>
<xa>name</xa>=<xs>'java.util.LinkedList_x003C_org.apache.juneau.samples.addressbook.Address_x003E_'</xs><xt>></xt>
<xt><sequence></xt>
<xt><choice</xt>
<xa>minOccurs</xa>=<xs>'0'</xs>
<xa>maxOccurs</xa>=<xs>'unbounded'</xs><xt>></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'address'</xs>
<xa>type</xa>=<xs>'addr:org.apache.juneau.samples.addressbook.Address'</xs><xt>/></xt>
- <xt><element</xt>
<xa>name</xa>=<xs>'null'</xs> <xa>type</xa>=<xs>'string'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'address'</xs>
<xa>_type</xa>=<xs>'addr:org.apache.juneau.samples.addressbook.Address'</xs><xt>/></xt>
+ <xt><element</xt>
<xa>name</xa>=<xs>'null'</xs> <xa>_type</xa>=<xs>'string'</xs><xt>/></xt>
<xt></choice></xt>
<xt></sequence></xt>
<xt></complexType></xt>
@@ -1143,18 +2274,18 @@
<xt><impor</xt>t
<xa>namespace</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
<xa>schemaLocation</xa>=<xs>'juneau.xsd'</xs><xt>/></xt>
<xt><import</xt>
<xa>namespace</xa>=<xs>'http://www.apache.org/address/'</xs>
<xa>schemaLocation</xa>=<xs>'addr.xsd'</xs><xt>/></xt>
<xt><import</xt>
<xa>namespace</xa>=<xs>'http://www.apache.org/mail/'</xs>
<xa>schemaLocation</xa>=<xs>'mail.xsd'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'person'</xs>
<xa>type</xa>=<xs>'per:org.apache.juneau.samples.addressbook.Person'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'person'</xs>
<xa>_type</xa>=<xs>'per:org.apache.juneau.samples.addressbook.Person'</xs><xt>/></xt>
<xt><complexType</xt>
<xa>name</xa>=<xs>'org.apache.juneau.samples.addressbook.Person'</xs><xt>></xt>
<xt><sequence></xt>
<xt><any</xt>
<xa>minOccurs</xa>=<xs>'0'</xs>
<xa>maxOccurs</xa>=<xs>'unbounded'</xs><xt>/></xt>
<xt></sequence></xt>
- <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>type</xa>=<xs>'string'</xs><xt>/></xt>
+ <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>_type</xa>=<xs>'string'</xs><xt>/></xt>
<xt></complexType></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'id'</xs>
<xa>type</xa>=<xs>'juneau:int'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'name'</xs>
<xa>type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'addressBookUri'</xs>
<xa>type</xa>=<xs>'juneau:java.net.URI'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'birthDate'</xs>
<xa>type</xa>=<xs>'juneau:java.util.Calendar'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'addresses'</xs>
<xa>type</xa>=<xs>'juneau:java.util.LinkedList_x003C_org.apache.juneau.samples.addressbook.Address_x003E_'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'id'</xs>
<xa>_type</xa>=<xs>'juneau:int'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'name'</xs>
<xa>_type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'addressBookUri'</xs>
<xa>_type</xa>=<xs>'juneau:java.net.URI'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'birthDate'</xs>
<xa>_type</xa>=<xs>'juneau:java.util.Calendar'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'addresses'</xs>
<xa>_type</xa>=<xs>'juneau:java.util.LinkedList_x003C_org.apache.juneau.samples.addressbook.Address_x003E_'</xs><xt>/></xt>
<xt></schema></xt>
[\u0000]
<xt><schema</xt>
@@ -1173,11 +2304,11 @@
<xt><sequence></xt>
<xt><any</xt>
<xa>minOccurs</xa>=<xs>'0'</xs>
<xa>maxOccurs</xa>=<xs>'unbounded'</xs><xt>/></xt>
<xt></sequence></xt>
- <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>type</xa>=<xs>'string'</xs><xt>/></xt>
+ <xt><attribute</xt> <xa>name</xa>=<xs>'uri'</xs>
<xa>_type</xa>=<xs>'string'</xs><xt>/></xt>
<xt></complexType></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'personUri'</xs>
<xa>type</xa>=<xs>'juneau:java.net.URI'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'id'</xs>
<xa>type</xa>=<xs>'juneau:int'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'isCurrent'</xs>
<xa>type</xa>=<xs>'juneau:boolean'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'personUri'</xs>
<xa>_type</xa>=<xs>'juneau:java.net.URI'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'id'</xs>
<xa>_type</xa>=<xs>'juneau:int'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'isCurrent'</xs>
<xa>_type</xa>=<xs>'juneau:boolean'</xs><xt>/></xt>
<xt></schema></xt>
[\u0000]
<xt><schema</xt>
@@ -1192,10 +2323,10 @@
<xt><import</xt>
<xa>namespace</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
<xa>schemaLocation</xa>=<xs>'juneau.xsd'</xs><xt>/></xt>
<xt><import</xt>
<xa>namespace</xa>=<xs>'http://www.apache.org/person/'</xs>
<xa>schemaLocation</xa>=<xs>'per.xsd'</xs><xt>/></xt>
<xt><import</xt>
<xa>namespace</xa>=<xs>'http://www.apache.org/address/'</xs>
<xa>schemaLocation</xa>=<xs>'addr.xsd'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'street'</xs>
<xa>type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'city'</xs>
<xa>type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'state'</xs>
<xa>type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
- <xt><element</xt> <xa>name</xa>=<xs>'zip'</xs>
<xa>type</xa>=<xs>'juneau:int'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'street'</xs>
<xa>_type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'city'</xs>
<xa>_type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'state'</xs>
<xa>_type</xa>=<xs>'juneau:java.lang.String'</xs><xt>/></xt>
+ <xt><element</xt> <xa>name</xa>=<xs>'zip'</xs>
<xa>_type</xa>=<xs>'juneau:int'</xs><xt>/></xt>
<xt></schema></xt>
</p>
<p>
@@ -1207,7 +2338,7 @@
<!--
========================================================================================================
-->
<a id="Recursion"></a>
- <h3 class='topic' onclick='toggle(this)'>2.6 - Non-tree models and
recursion detection</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.7 - Non-tree models and
recursion detection</h3>
<div class='topic'>
<p>
The XML serializer is designed to be used against POJO
tree structures. <br>
@@ -1280,7 +2411,7 @@
<!--
========================================================================================================
-->
<a id="SerializerConfigurableProperties"></a>
- <h3 class='topic' onclick='toggle(this)'>2.7 - Configurable
properties</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.8 - Configurable
properties</h3>
<div class='topic'>
<p>
See the following classes for all configurable
properties that can be used on this serializer:
@@ -1294,7 +2425,7 @@
<!--
========================================================================================================
-->
<a id="SerializerOtherNotes"></a>
- <h3 class='topic' onclick='toggle(this)'>2.8 - Other notes</h3>
+ <h3 class='topic' onclick='toggle(this)'>2.9 - Other notes</h3>
<div class='topic'>
<ul class='spaced-list'>
<li>Like all other Juneau serializers, the XML
serializer is thread safe and maintains an internal cache of bean classes
encountered.<br>
@@ -1324,6 +2455,7 @@
<p class='bcode'>
<jc>// Create a new serializer with readable output.</jc>
XmlSerializer s = <jk>new</jk> XmlSerializer()
+
.setProperty(XmlSerializerContext.<jsf>XML_enableNamespaces</jsf>,
<jk>true</jk>)
.setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>,
<jk>true</jk>)
.setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>,
<js>'\''</js>);
@@ -1352,7 +2484,6 @@
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
<xa>xmlns:addr</xa>=<xs>'http://www.apache.org/address/'</xs>
<xa>xmlns:mail</xa>=<xs>'http://www.apache.org/mail/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
<xt><per:id></xt>1<xt></per:id></xt>
<xt><per:name></xt>John Smith<xt></per:name></xt>
@@ -1430,180 +2561,6 @@
the parser will use <code>ObjectMap</code> and
<code>ObjectList</code> by default.
</p>
-
- <!--
========================================================================================================
-->
- <a id="AddJsonTypeAttr"></a>
- <h3 class='topic' onclick='toggle(this)'>3.1.1 - Serializing
with JSON-type attributes</h3>
- <div class='topic'>
- <p>
- In some circumstances, the XML parser needs
additional information to recreate the original
- data structure when various annotations
(e.g. {@link org.apache.juneau.xml.annotation.Xml#childName()}, {@link
org.apache.juneau.xml.annotation.Xml#format()})
- are used.
- </p>
- <p>
- For example, starting with this XML:
- </p>
- <p class='bcode'>
- <xt><per:person</xt>
-
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
-
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
-
<xa>xmlns:addr</xa>=<xs>'http://www.apache.org/address/'</xs>
-
<xa>xmlns:mail</xa>=<xs>'http://www.apache.org/mail/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
-
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
- <xt><per:id></xt>1<xt></per:id></xt>
- <xt><per:name></xt>John Smith<xt></per:name></xt>
-
<xt><per:addressBookUri></xt>http://sample/addressBook<xt></per:addressBookUri></xt>
-
<xt><per:birthDate></xt>1946-08-12T04:00:00Z<xt></per:birthDate></xt>
- <xt><per:addresses></xt>
- <xt><addr:address</xt>
<xa>uri</xa>=<xs>'http://sample/addressBook/address/1'</xs><xt>></xt>
-
<xt><addr:personUri></xt>http://sample/addressBook/person/1<xt></addr:personUri></xt>
-
<xt><addr:id></xt>1<xt></addr:id></xt>
- <xt><mail:street></xt>100 Main
Street<xt></mail:street></xt>
-
<xt><mail:city></xt>Anywhereville<xt></mail:city></xt>
-
<xt><mail:state></xt>NY<xt></mail:state></xt>
-
<xt><mail:zip></xt>12345<xt></mail:zip></xt>
-
<xt><addr:isCurrent></xt>true<xt></addr:isCurrent></xt>
- <xt></addr:address></xt>
- <xt></per:addresses></xt>
- <xt></per:person></xt>
- </p>
- <p>
- Let's try to parse this into an
<code>ObjectMap</code>.
- </p>
- <p class='bcode'>
- <jc>// Parse XML into a generic POJO model.</jc>
- ObjectMap m = XmlParser.<jsf>DEFAULT</jsf>.parse(xml,
ObjectMap.<jk>class</jk>);
-
- <jc>// Convert it to JSON.</jc>
- String json =
JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(m);
- </p>
- <p>
- What we end up with is the following:
- </p>
- <p class='bcode'>
- {
- uri: <js>'http://sample/addressBook/person/1'</js>,
- id: <js>'1'</js>,
- name: <js>'John Smith'</js>,
- addressBookUri: <js>'http://sample/addressBook'</js>,
- birthDate: <js>'1946-08-12T04:00:00Z'</js>,
- addresses: {
- address: {
- uri:
<js>'http://sample/addressBook/address/1'</js>,
- personUri:
<js>'http://sample/addressBook/person/1'</js>,
- id: <js>'1'</js>,
- street: <js>'100 Main Street'</js>,
- city: <js>'Anywhereville'</js>,
- state: <js>'NY'</js>,
- zip: <js>'12345'</js>,
- isCurrent: <js>'true'</js>
- }
- }
- }
- </p>
- <p>
- Note that the addresses field does not parse
correctly as an array of addresses.<br>
- Without the beans providing meta-information
about the data structure, the XML
- parser has no way of determining that
it's an array.
- </p>
- <p>
- To preserve this information, the {@link
org.apache.juneau.xml.XmlSerializerContext#XML_addJsonTypeAttrs
XML_addJsonTypeAttrs} property
- is provided that will insert
<xa>type</xa> attributes into the XML to preserve JSON equivalency in the
document when it cannot be determined automatically.
- </p>
- <h6 class='figure'>Example with XML_addJsonTypeAttrs
setting enabled</h6>
- <p class='bcode'>
- <jc>// Create a new serializer with readable output.</jc>
- XmlSerializer s = <jk>new</jk> XmlSerializer()
-
.setProperty(SerializerContext.<jsf>SERIALIZER_useIndentation</jsf>,
<jk>true</jk>)
- .setProperty(SerializerContext.<jsf>SERIALIZER_quoteChar</jsf>,
<js>'\''</js>)
-
.setProperty(XmlSerializerContext.<jsf>XML_addJsonTypeAttrs</jsf>,
<jk>true</jk>);
- </p>
- <h6 class='figure'>Results</h6>
- <p class='bcode'>
- <xt><per:person</xt>
-
<xa>xmlns</xa>=<xs>'http://www.apache.org/2013/Juneau'</xs>
-
<xa>xmlns:per</xa>=<xs>'http://www.apache.org/person/'</xs>
-
<xa>xmlns:addr</xa>=<xs>'http://www.apache.org/address/'</xs>
-
<xa>xmlns:mail</xa>=<xs>'http://www.apache.org/mail/'</xs>
-
<xa>xmlns:xsi</xa>=<xs>'http://www.w3.org/2001/XMLSchema-instance'</xs>
-
<xa>uri</xa>=<xs>'http://sample/addressBook/person/1'</xs><xt>></xt>
- <xt><per:id</xt>
<xa>type</xa>=<xs>'number'</xs><xt>></xt>1<xt></per:id></xt>
- <xt><per:name></xt>John Smith<xt></per:name></xt>
-
<xt><per:addressBookUri></xt>http://sample/addressBook<xt></per:addressBookUri></xt>
-
<xt><per:birthDate></xt>1946-08-12T04:00:00Z<xt></per:birthDate></xt>
- <xt><per:addresses</xt>
<xa>type</xa>=<xs>'array'</xs><xt>></xt>
- <xt><addr:address</xt>
<xa>uri</xa>=<xs>'http://sample/addressBook/address/1'</xs><xt>></xt>
-
<xt><addr:personUri></xt>http://sample/addressBook/person/1<xt></addr:personUri></xt>
- <xt><addr:id</xt>
<xa>type</xa>=<xs>'number'</xs><xt>></xt>1<xt></addr:id></xt>
- <xt><mail:street></xt>100 Main
Street<xt></mail:street></xt>
-
<xt><mail:city></xt>Anywhereville<xt></mail:city></xt>
-
<xt><mail:state></xt>NY<xt></mail:state></xt>
- <xt><mail:zip</xt>
<xa>type</xa>=<xs>'number'</xs><xt>></xt>12345<xt></mail:zip></xt>
- <xt><addr:isCurrent</xt>
<xa>type</xa>=<xs>'boolean'</xs><xt>></xt>true<xt></addr:isCurrent></xt>
- <xt></addr:address></xt>
- <xt></per:addresses></xt>
- <xt></per:person></xt>
- </p>
- <p>
- Notice the various <xa>type</xa> attributes
that have been added to the output.
- </p>
- <p>
- Now when we parse this into an
<code>ObjectMap</code> and serialize it to JSON, we get the following:
- </p>
- <p class='bcode'>
- {
- uri: <js>'http://sample/addressBook/person/1'</js>,
- id: <jk>1</jk>,
- name: <js>'John Smith'</js>,
- addressBookUri: <js>'http://sample/addressBook'</js>,
- birthDate: <js>'1946-08-12T04:00:00Z'</js>,
- addresses: [
- {
- uri:
<js>'http://sample/addressBook/address/1'</js>,
- personUri:
<js>'http://sample/addressBook/person/1'</js>,
- id: <jk>1</jk>,
- street: <js>'100 Main Street'</js>,
- city: <js>'Anywhereville'</js>,
- state: <js>'NY'</js>,
- zip: <jk>12345</jk>,
- isCurrent: <jk>true</jk>
- }
- ]
- }
- </p>
- <p>
- Once parsed into a generic model, various
convenience methods are provided on the <code>ObjectMap</code>
- and <code>ObjectList</code> classes to
retrieve values:
- </p>
- <p class='bcode'>
- <jc>// Parse XML into a generic POJO model.</jc>
- ObjectMap m = XmlParser.<jsf>DEFAULT</jsf>.parse(xml,
ObjectMap.<jk>class</jk>);
-
- <jc>// Get some simple values.</jc>
- String name = m.getString(<js>"name"</js>);
- <jk>int</jk> id = m.getInt(<js>"id"</js>);
-
- <jc>// Get a value convertable from a String.</jc>
- URI uri = m.get(URI.<jk>class</jk>, <js>"uri"</js>);
-
- <jc>// Get a value using a transform.</jc>
- CalendarSwap transform = <jk>new</jk> CalendarSwap.ISO8601DTZ();
- Calendar birthDate = m.get(transform, <js>"birthDate"</js>);
-
- <jc>// Get the addresses.</jc>
- ObjectList addresses = m.getObjectList(<js>"addresses"</js>);
-
- <jc>// Get the first address and convert it to a bean.</jc>
- Address address = addresses.get(Address.<jk>class</jk>, 0);
- </p>
- </div>
-
- <p>
- As a general rule, parsing into beans is often more
efficient than parsing into generic models.<br>
- And working with beans is often less error prone than
working with generic models.
- </p>
- </div>
<!--
========================================================================================================
-->
<a id="ParserConfigurableProperties"></a>