UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

287 lines (280 loc) 42.4 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>JAXB Code Binding and Generation</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="JAXB Code Binding and Generation"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-24-SECT-8"/>JAXB Code Binding and Generation</h1></div></div></div><p>We’ve said that our ultimate goal in this chapter is automated binding of XML to Java classes. Now we’ll discuss the standard Java API for XML Binding, JAXB. (This should not be confused with JAXP, the parser API.) JAXB is a standard extension that is bundled with Java 6 and later. With JAXB, the developer does not need to create any fragile parsing code. An XML schema or Java code can be used as the starting point for transforming XML to Java and back. (“Schema first” and “code first” are both supported.) With JAXB, you can either mark up your Java classes with simple annotations that map (bind) them to XML or start with an XML schema and generate plain Java classes (POJOs) with the necessary annotations included. You can even derive an XML schema from your Java classes to use as a starting point or contract with non-Java systems.</p><p>At runtime, JAXB can read an XML document and parse it into the model that you have defined or you can go the other way, populating your object model and then writing it out to XML. In both cases, JAXB can validate the data to make sure it matches a schema. This may sound like the DOM interface, but in this case we’re not using generic classes—we’re using our own model. In this section, we’ll reuse the class model that we created for the SAX example with our <span class="emphasis"><em>zooinventory.xml</em></span> file. We’ll use the familiar <code class="literal">Inventory</code>, <code class="literal">Animal</code>, and <code class="literal">FoodRecipe</code> classes directly, but this time you’ll see that we’ll be more focused on the schema and names and less on the parsing machinery.</p><div class="sect2" title="Annotating Our Model"><div class="titlepage"><div><div><h2 class="title"><a id="id1325072"/>Annotating Our Model</h2></div></div></div><p><a id="idx11195" class="indexterm"/> <a id="idx11214" class="indexterm"/>JAXB gives us a great deal of flexibility in mapping our Java classes to XML elements and there are a lot of special cases. But if we accept most of the default behavior for our model, we can get started with very little work. Let’s start by taking our zoo inventory classes and adding the necessary annotations to allow JAXB to bind it to XML:</p><a id="I_programlisting24_id835157"/><pre class="programlisting"><code class="nd">@XmlRootElement</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">Inventory</code> <code class="o">{</code> <code class="kd">public</code> <code class="n">List</code><code class="o">&lt;</code><code class="n">Animal</code><code class="o">&gt;</code> <code class="n">animal</code> <code class="o">=</code> <code class="k">new</code> <code class="n">ArrayList</code><code class="o">&lt;&gt;();</code> <code class="o">}</code></pre><p>Well, that was easy! Yes, in fact as we hinted at the beginning of the chapter, adding just the <a id="I_indexterm24_id835167" class="indexterm"/><code class="literal">@XmlRootElement</code> annotation to the “top level” or root class of our model will yield nearly the same XML that we used before. To generate the XML, we’ll use the following test harness:</p><a id="I_programlisting24_id835184"/><pre class="programlisting"> <code class="kn">import</code> <code class="nn">javax.xml.bind.JAXBContext</code><code class="o">;</code> <code class="kn">import</code> <code class="nn">javax.xml.bind.JAXBException</code><code class="o">;</code> <code class="kn">import</code> <code class="nn">javax.xml.bind.Marshaller</code><code class="o">;</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">TestJAXBMarshall</code> <code class="o">{</code> <code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code> <code class="n">String</code> <code class="o">[]</code> <code class="n">args</code> <code class="o">)</code> <code class="kd">throws</code> <code class="n">JAXBException</code> <code class="o">{</code> <code class="n">Inventory</code> <code class="n">inventory</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Inventory</code><code class="o">();</code> <code class="n">FoodRecipe</code> <code class="n">recipe</code> <code class="o">=</code> <code class="k">new</code> <code class="n">FoodRecipe</code><code class="o">();</code> <code class="n">recipe</code><code class="o">.</code><code class="na">name</code> <code class="o">=</code> <code class="s">"Gorilla Chow"</code><code class="o">;</code> <code class="n">recipe</code><code class="o">.</code><code class="na">ingredient</code><code class="o">.</code><code class="na">addAll</code><code class="o">(</code> <code class="n">Arrays</code><code class="o">.</code><code class="na">asList</code><code class="o">(</code> <code class="s">"leaves"</code><code class="o">,</code> <code class="s">"insects"</code><code class="o">,</code> <code class="s">"fruit"</code> <code class="o">)</code> <code class="o">);</code> <code class="n">Animal</code> <code class="n">animal</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Animal</code><code class="o">(</code> <code class="n">Animal</code><code class="o">.</code><code class="na">AnimalClass</code><code class="o">.</code><code class="na">mammal</code><code class="o">,</code> <code class="s">"Song Fang"</code><code class="o">,</code> <code class="s">"Giant Panda"</code><code class="o">,</code> <code class="s">"China"</code><code class="o">,</code> <code class="s">"Bamboo"</code><code class="o">,</code> <code class="s">"Friendly"</code><code class="o">,</code> <code class="mf">45.0</code><code class="o">,</code> <code class="n">recipe</code> <code class="o">);</code> <code class="n">inventory</code><code class="o">.</code><code class="na">animal</code><code class="o">.</code><code class="na">add</code><code class="o">(</code> <code class="n">animal</code> <code class="o">);</code> <code class="n">marshall</code><code class="o">(</code> <code class="n">inventory</code> <code class="o">);</code> <code class="o">}</code> <code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">marshall</code><code class="o">(</code> <code class="n">Object</code> <code class="n">jaxbObject</code> <code class="o">)</code> <code class="kd">throws</code> <code class="n">JAXBException</code> <code class="o">{</code> <code class="n">JAXBContext</code> <code class="n">context</code> <code class="o">=</code> <code class="n">JAXBContext</code><code class="o">.</code><code class="na">newInstance</code><code class="o">(</code> <code class="n">jaxbObject</code><code class="o">.</code><code class="na">getClass</code><code class="o">()</code> <code class="o">);</code> <code class="n">Marshaller</code> <code class="n">marshaller</code> <code class="o">=</code> <code class="n">context</code><code class="o">.</code><code class="na">createMarshaller</code><code class="o">();</code> <code class="n">marshaller</code><code class="o">.</code><code class="na">setProperty</code><code class="o">(</code><code class="n">Marshaller</code><code class="o">.</code><code class="na">JAXB_FORMATTED_OUTPUT</code><code class="o">,</code> <code class="n">Boolean</code><code class="o">.</code><code class="na">TRUE</code><code class="o">);</code> <code class="n">marshaller</code><code class="o">.</code><code class="na">marshal</code><code class="o">(</code><code class="n">jaxbObject</code><code class="o">,</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">);</code> <code class="o">}</code> <code class="o">}</code></pre><p>We’ve taken the liberty of adding some constructors to shorten the code for creating the model, but it doesn’t change the behavior here. It’s just the four lines of our <code class="literal">marshall()</code> method that actually use JAXB to write out the XML. We first create a <a id="I_indexterm24_id835211" class="indexterm"/><code class="literal">JAXBContext</code>, passing in the class type to be marshalled. We’ve made our <code class="literal">marshall()</code> method somewhat reusable by getting the class type from the object passed in. However, it’s sometimes necessary to pass in additional classes to the <code class="literal">newInstance()</code> method in order for JAXB to be aware of all of the bound classes that may be needed. In that case, we’d simpy pass more class types to the <code class="literal">newInstance()</code> method (it accepts a variable argument list with any number of arguments—of class types). We then create a <code class="literal">Marshaller</code> from the context and, for our purposes, set a flag indicating that we would like nice, human-readable output (the default output is one long line of XML). Finally, we tell the marshaller to send our object to <code class="literal">System.out</code>.</p><p>The output looks like this:</p><a id="I_programlisting24_id835261"/><pre class="programlisting"><code class="o">&lt;?</code><code class="n">xml</code> <code class="n">version</code><code class="o">=</code><code class="s">"1.0"</code> <code class="n">encoding</code><code class="o">=</code><code class="s">"UTF-8"</code> <code class="n">standalone</code><code class="o">=</code><code class="s">"yes"</code><code class="o">?&gt;</code> <code class="o">&lt;</code><code class="n">inventory</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">animal</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">animalClass</code><code class="o">&gt;</code><code class="n">mammal</code><code class="o">&lt;/</code><code class="n">animalClass</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">name</code><code class="o">&gt;</code><code class="n">Song</code> <code class="n">Fang</code><code class="o">&lt;/</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">species</code><code class="o">&gt;</code><code class="n">Giant</code> <code class="n">Panda</code><code class="o">&lt;/</code><code class="n">species</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">habitat</code><code class="o">&gt;</code><code class="n">China</code><code class="o">&lt;/</code><code class="n">habitat</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">food</code><code class="o">&gt;</code><code class="n">Bamboo</code><code class="o">&lt;/</code><code class="n">food</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">temperament</code><code class="o">&gt;</code><code class="n">Friendly</code><code class="o">&lt;/</code><code class="n">temperament</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">weight</code><code class="o">&gt;</code><code class="mf">45.0</code><code class="o">&lt;/</code><code class="n">weight</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">animal</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">animal</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">animalClass</code><code class="o">&gt;</code><code class="n">mammal</code><code class="o">&lt;/</code><code class="n">animalClass</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">name</code><code class="o">&gt;</code><code class="n">Cocoa</code><code class="o">&lt;/</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">species</code><code class="o">&gt;</code><code class="n">Gorilla</code><code class="o">&lt;/</code><code class="n">species</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">habitat</code><code class="o">&gt;</code><code class="n">Ceneral</code> <code class="n">Africa</code><code class="o">&lt;/</code><code class="n">habitat</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">temperament</code><code class="o">&gt;</code><code class="n">Know</code><code class="o">-</code><code class="n">it</code><code class="o">-</code><code class="n">all</code><code class="o">&lt;/</code><code class="n">temperament</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">weight</code><code class="o">&gt;</code><code class="mf">45.0</code><code class="o">&lt;/</code><code class="n">weight</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">foodRecipe</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">name</code><code class="o">&gt;</code><code class="n">Gorilla</code> <code class="n">Chow</code><code class="o">&lt;/</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">ingredient</code><code class="o">&gt;</code><code class="n">fruit</code><code class="o">&lt;/</code><code class="n">ingredient</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">ingredient</code><code class="o">&gt;</code><code class="n">shoots</code><code class="o">&lt;/</code><code class="n">ingredient</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">ingredient</code><code class="o">&gt;</code><code class="n">leaves</code><code class="o">&lt;/</code><code class="n">ingredient</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">foodRecipe</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">animal</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">inventory</code><code class="o">&gt;</code></pre><p>As we said, it’s almost identical to the XML we worked with earlier. Admittedly, we chose to create our XML using the same (common) conventions that JAXB uses, so it’s not entirely magic. The first thing to notice is that JAXB automatically mapped our class names to lowercase XML element names (e.g., class <code class="literal">Animal</code> to <code class="literal">&lt;animal&gt;</code>). If we had used JavaBeans-style getter methods instead of public fields, the same would be true; for example, a <code class="literal">getSpecies()</code> method would produce a default element name of <code class="literal">species</code>.</p><p>If we wanted to map our class names and property names to completely different XML names, we could easily accomplish that using the name attribute of the <a id="I_indexterm24_id835310" class="indexterm"/><code class="literal">@XmlRootElement</code> and <a id="I_indexterm24_id835323" class="indexterm"/><code class="literal">@XmlElement</code> annotations. For example, we can call our <code class="literal">Animal</code> “creature” and rename <code class="literal">temperament</code> to “personality” like so:</p><a id="I_programlisting24_id835348"/><pre class="programlisting"><code class="nd">@XmlRootElement</code><code class="o">(</code><code class="n">name</code><code class="o">=</code><code class="s">"creature"</code><code class="o">)</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">Animal</code> <code class="o">{</code> <code class="o">...</code> <code class="nd">@XmlElement</code><code class="o">(</code><code class="n">name</code><code class="o">=</code><code class="s">"personality"</code><code class="o">)</code> <code class="kd">public</code> <code class="n">String</code> <code class="n">temperament</code><code class="o">;</code></pre><p>The real difference between our generated XML and our earlier sample is that our <code class="literal">animalClass</code> attribute is not acting like an attribute. By default, is has been mapped to an element, like the other properties of <code class="literal">Animal</code>. We can rectify that with another annotation, <code class="literal">@XmlAttribute</code>:</p><a id="I_programlisting24_id835376"/><pre class="programlisting"><code class="kd">public</code> <code class="kd">class</code> <code class="nc">Animal</code> <code class="o">{</code> <code class="nd">@XmlAttribute</code> <code class="kd">public</code> <code class="n">AnimalClass</code> <code class="n">animalClass</code><code class="o">;</code> <code class="o">...</code> <code class="c1">// Produces...</code> <code class="o">&lt;</code><code class="n">inventory</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">animal</code> <code class="n">animalClass</code><code class="o">=</code><code class="s">"mammal"</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">name</code><code class="o">&gt;</code><code class="n">Song</code> <code class="n">Fang</code><code class="o">&lt;/</code><code class="n">name</code><code class="o">&gt;</code></pre><p>Also note that JAXB has shown the <code class="literal">food</code> element in the first animal and the <code class="literal">foodRecipe</code> in the second. JAXB will ignore a field or property that is <code class="literal">null</code> (as is the case here) unless you specify that the property is “nillable” using <code class="literal">@XmlElement(nillable=true)</code>. That behavior automatically supported the alternation between our two properties.</p><p><a id="idx11187" class="indexterm"/>There are many additional annotations that provide support for mapping Java classes, fields, and properties to other features of XML. <a class="xref" href="ch24s09.html#t2406" title="Table 24-6. JAXB Annotations">Table 24-6</a> attempts to provide a concise description of what each annotation is used for. Some of the usages get a little complex,so you may want to refer to the Javadoc for more details.</p><p><a id="I_indexterm24_id835435" class="indexterm"/> <a id="I_indexterm24_id835444" class="indexterm"/> <a id="I_indexterm24_id835453" class="indexterm"/> <a id="I_indexterm24_id835462" class="indexterm"/> <a id="I_indexterm24_id835471" class="indexterm"/> <a id="I_indexterm24_id835480" class="indexterm"/> <a id="I_indexterm24_id835489" class="indexterm"/> <a id="I_indexterm24_id835498" class="indexterm"/> <a id="I_indexterm24_id835507" class="indexterm"/> <a id="I_indexterm24_id835516" class="indexterm"/> <a id="I_indexterm24_id835525" class="indexterm"/> <a id="I_indexterm24_id835534" class="indexterm"/> <a id="I_indexterm24_id835543" class="indexterm"/> <a id="I_indexterm24_id835552" class="indexterm"/> <a id="I_indexterm24_id835560" class="indexterm"/> <a id="I_indexterm24_id835570" class="indexterm"/> <a id="I_indexterm24_id835578" class="indexterm"/> <a id="I_indexterm24_id835587" class="indexterm"/> <a id="I_indexterm24_id835596" class="indexterm"/> <a id="I_indexterm24_id835605" class="indexterm"/> <a id="I_indexterm24_id835614" class="indexterm"/> <a id="I_indexterm24_id835623" class="indexterm"/> <a id="I_indexterm24_id835632" class="indexterm"/> <a id="I_indexterm24_id835641" class="indexterm"/> <a id="I_indexterm24_id835650" class="indexterm"/> <a id="I_indexterm24_id835659" class="indexterm"/> <a id="I_indexterm24_id835668" class="indexterm"/> </p><div class="table"><a id="t2406"/><p class="title">Table 24-6. JAXB Annotations</p><div class="table-contents"><table summary="JAXB Annotations" style="border: none;"><colgroup><col/><col/></colgroup><thead><tr><th style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; ">Annotation</th><th style="border-bottom: 0.5pt solid ; ">Description</th></tr></thead><tbody><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlAccessorOrder</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a package or class to set alphabetic ordering of marshalled fields and properties. (The default ordering is undefined.) See <code class="literal">@XmlType</code> to specify the ordering yourself. As a reminder: package-level annotations in Java are placed on a (lonely) package statement in a special file named <em class="filename">package-info.java</em> within the corresponding package structure. (See <a class="xref" href="ch07s04.html" title="Annotations">Annotations</a>.)</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlAccessorType</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a package or class to specify whether fields and properties are marshalled by default. You can choose: only fields, only properties (getters/setters), none (only those annotated by the user), or all public fields and properties. See <code class="literal">@XmlTransient</code> to exclude items.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlAnyAttribute</code></td><td style="border-bottom: 0.5pt solid ; ">Designates a Java <code class="literal">Map</code> object to receive any unbound XML attribute name-value pairs for an entity (i.e., the <code class="literal">Map</code> will collect any leftover attributes for which no corresponding property or field can be found).</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlAnyElement</code></td><td style="border-bottom: 0.5pt solid ; ">Designates a Java <code class="literal">List</code> or <code class="literal">Array</code> object to receive any unbound XML elements for an entity (i.e., the <code class="literal">List</code> will accumulate any leftover elements for which no corresponding property or field can be found).</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlAttachmentRef</code></td><td style="border-bottom: 0.5pt solid ; ">Designates a <code class="literal">java.activation.DataHandler</code> object to handle an XML MIME attachment.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlAttribute</code></td><td style="border-bottom: 0.5pt solid ; ">Binds a Java field or property to an XML attribute. The <code class="literal">name</code> attribute can be used to specify an XML attribute name that is different from the name of the field or property. Use the <code class="literal">required</code> attribute to specify whether the attribute is required.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlElement</code></td><td style="border-bottom: 0.5pt solid ; ">Binds a a Java field or property to an XML element. The <code class="literal">name</code> attribute can be used to specify an XML element name different from the name of the field or property. Use the <code class="literal">required</code> attribute to specify whether the element is required.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlElements</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a Java collection to specify distinct element names for contained items based on their Java type. Holds a list of <code class="literal">@XmlElement</code> annotations with <code class="literal">name</code> and <code class="literal">type</code> attributes that explicitly map Java types in the collection to XML element names (e.g., in our example, <code class="literal">inventory</code> contains <code class="literal">animal</code> elements because our List property is named “animal”). If we chose to have subclasses of <code class="literal">Animal</code> in our inventory collection, we could map them to XML element names such as <code class="literal">gorilla</code> and <code class="literal">lemur</code>. See <code class="literal">@XmlElementRef</code>.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlElementRef</code></td><td style="border-bottom: 0.5pt solid ; ">Similar to <code class="literal">@XmlElements</code>, used to generate individualized names for Java types in a collection. However, instead of the names for each type being specified directly, they are determined at runtime by the individual types’ Java type bindings (e.g., in our example, <code class="literal">inventory</code> contains <code class="literal">animal</code> elements because our List is named “animal”). Using <code class="literal">@XmlElementRef</code>, we could subclass <code class="literal">Animal</code> and have our <code class="literal">inventory</code> contain elements like <code class="literal">gorilla</code> and <code class="literal">lemur</code>, with the names determined by <code class="literal">@XmlRootElement</code> annotations on the respective subclasses. See important class binding info in <code class="literal">@XmlElementRefs</code>.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlElementRefs</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a Java collection to provide a list of <code class="literal">@XmlElementRef</code> annotations with <code class="literal">type</code> attributes that explicitly specify the Java types that may appear in the collection. The effect is the same as using a simple <code class="literal">@XmlElementRef</code> on the collection, but we actively tell JAXB the class names that have bindings. If not supplied in this way, we have to provide the full list of bound classes to the <code class="literal">JAXBContext</code><code class="literal">newInstance()</code> method in order for them to be recognized.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlElementWrapper</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a Java collection to cause the sequence of XML elements to be wrapped in the specified element instead of appearing directly inline in the XML (e.g., our <code class="literal">animal</code> elements appear directly in <code class="literal">inventory</code>). Using this annotation, we could nest them all within a new <code class="literal">animals</code> element.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlEnum</code></td><td style="border-bottom: 0.5pt solid ; ">Binds a Java Enum to XML and allows <code class="literal">@XmlEnum</code>Values annotations to be used to map the enum values for XML if required.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlEnumValue</code></td><td style="border-bottom: 0.5pt solid ; ">Binds an individual Java Enum value to a string to be used in the XML (e.g., our <code class="literal">mammal</code> enum value could be mapped to “mammalia”).</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlID</code></td><td style="border-bottom: 0.5pt solid ; ">Supports referential integrity by designating a Java property or field of a class as being the XML <code class="literal">ID</code> attribute (a unique key) for the XML element within the document.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlIDREF</code></td><td style="border-bottom: 0.5pt solid ; ">Supports referential integrity by designating a Java property or field as an <code class="literal">idref</code> attribute pointing to an element with an <code class="literal">@XmlID</code>. The annotated property or field must contain an instance of a Java type containing an <code class="literal">@XmlID</code> annotation. When marshalled, the attribute name will be the property name and the value will be the contained XML ID value.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlInlineBinaryData</code></td><td style="border-bottom: 0.5pt solid ; ">Bind a Java byte array to receive base64 binary data encoded in the XML.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlList</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a Java collection to map items to a single simple content element with a whitespace-separated list of values instead of a series of elements.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlMimeType</code></td><td style="border-bottom: 0.5pt solid ; ">Used with a Java Image or Source type to specify a MIME type for XML base64-encoded binary data bound to it.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlMixed</code></td><td style="border-bottom: 0.5pt solid ; ">Binds a Java object collection to XML “mixed content” (i.e., XML containing both text and element tags within it). Text will be added to the collection as <code class="literal">String</code> objects interleaved with the usual Java types representing the other elements.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlRootElement</code></td><td style="border-bottom: 0.5pt solid ; ">Bind a Java class to an XML element optionally provide a name. This is the minimum annotation required on your class to make it possible to marshal it to XML and back.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlElementDecl</code></td><td style="border-bottom: 0.5pt solid ; ">Used in binding XML schema elements to methods in Java object factories created in some code generation scenarios.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlRegistry</code></td><td style="border-bottom: 0.5pt solid ; ">Used with <code class="literal">@XmlElementDecl</code> in designating Java object factories used in some code generation scenarios.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlSchema</code></td><td style="border-bottom: 0.5pt solid ; ">Binds a Java package to a default XML namespace.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlNs</code></td><td style="border-bottom: 0.5pt solid ; ">Used with <code class="literal">@XmlSchema</code> to bind a Java package to one or more XML namespace prefixes.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlSchemaType</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a Java property, field, or package. Specifies a Java type to be used for a standard XML schema built-in types, such as date or a numeric type.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlSchemaTypes</code></td><td style="border-bottom: 0.5pt solid ; ">Used on a Java package. Holds a list of <code class="literal">@XmlSchemaType</code> annotations mapping Java types to built-in XML schema types.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlTransient</code></td><td style="border-bottom: 0.5pt solid ; ">Designates that a Java property or field should not be marshaled to the XML. This can be used in conjunction with defaults that marshal all properties or fields to exclude individual items. See <code class="literal">@XmlAccessorType</code>.</td></tr><tr><td style="border-right: 0.5pt solid ; border-bottom: 0.5pt solid ; "><code class="literal">@XmlType</code></td><td style="border-bottom: 0.5pt solid ; ">Binds a Java class to an XML schema type. Additionally, the <code class="literal">propOrder</code> attribute may be used to explicitly list the order in which elements are marshalled to XML.</td></tr><tr><td style="border-right: 0.5pt solid ; "><code class="literal">@XmlValue</code></td><td style="">Designates that a Java property or field contains the “simple” XML content for the Java type; that is, instead of marshalling the class as an XML element containing a nested element for the property, the value of the annotated property will appear directly as the content. The Java type may have only one property designated as <code class="literal">@XmlValue</code>.<a id="I_indexterm24_id836311" class="indexterm"/></td></tr></tbody></table></div></div><div class="sect3" title="Unmarshalling from XML"><div class="titlepage"><div><div><h3 class="title"><a id="id2017277"/>Unmarshalling from XML</h3></div></div></div><p>Creating our object model from XML just requires a few lines to create an <code class="literal">Unmarshaller</code> from our <code class="literal">JAXBContext</code> and a cast to the Java type of our root element:</p><a id="I_programlisting24_id836336"/><pre class="programlisting"><code class="n">JAXBContext</code> <code class="n">context</code> <code class="o">=</code> <code class="n">JAXBContext</code><code class="o">.</code><code class="na">newInstance</code><code class="o">(</code> <code class="n">Inventory</code><code class="o">.</code><code class="na">class</code> <code class="o">);</code> <code class="n">Unmarshaller</code> <code class="n">unmarshaller</code> <code class="o">=</code> <code class="n">context</code><code class="o">.</code><code class="na">createUnmarshaller</code><code class="o">();</code> <code class="n">Inventory</code> <code class="n">inventory</code> <code class="o">=</code> <code class="o">(</code><code class="n">Inventory</code><code class="o">)</code><code class="n">unmarshaller</code><code class="o">.</code><code class="na">unmarshal</code><code class="o">(</code> <code class="k">new</code> <code class="nf">File</code><code class="o">(</code><code class="s">"zooinventory.xml"</code><code class="o">)</code> <code class="o">);</code></pre><p>The <a id="I_indexterm24_id836346" class="indexterm"/><code class="literal">Unmarshaller</code> class has a <a id="I_indexterm24_id836357" class="indexterm"/><code class="literal">setValidating()</code> method like the <code class="literal">SAXParser</code>, but it is deprecated. Instead, we could use the <a id="I_indexterm24_id836374" class="indexterm"/><code class="literal">setSchema()</code> method to set an XML Schema representation if we want validation as part of the parsing process. Alternately, we could just validate the schema separately. See <a class="xref" href="ch24s08.html#learnjava3-CHP-24-SECT-7.3" title="XML Schema">XML Schema</a>.<a id="I_indexterm24_id836393" class="indexterm"/><a id="I_indexterm24_id836400" class="indexterm"/></p></div></div><div class="sect2" title="Generating a Java Model from an XML Schema"><div class="titlepage"><div><div><h2 class="title"><a id="id2017235"/>Generating a Java Model from an XML Schema</h2></div></div></div><p><a id="idx11196" class="indexterm"/> <a id="idx11215" class="indexterm"/>If you are starting with an XML Schema (<span class="emphasis"><em>xsd</em></span> file), you can generate annotated Java classes from the schema using the JAXB <a id="I_indexterm24_id836446" class="indexterm"/><code class="literal">xjc</code> command-line tool that comes with the JDK.</p><a id="I_programlisting24_id836457"/><pre class="programlisting"><code class="n">xjc</code> <code class="n">zooinventory</code><code class="o">.</code><code class="na">xsd</code> <code class="c1">// Output</code> <code class="n">parsing</code> <code class="n">a</code> <code class="n">schema</code><code class="o">...</code> <code class="n">compiling</code> <code class="n">a</code> <code class="n">schema</code><code class="o">...</code> <code class="n">generated</code><code class="o">/</code><code class="n">Animal</code><code class="o">.</code><code class="na">java</code> <code class="n">generated</code><code class="o">/</code><code class="n">FoodRecipe</code><code class="o">.</code><code class="na">java</code> <code class="n">generated</code><code class="o">/</code><code class="n">Inventory</code><code class="o">.</code><code class="na">java</code> <code class="n">generated</code><code class="o">/</code><code class="n">ObjectFactory</code><code class="o">.</code><code class="na">java</code></pre><p>By default, the output is placed in the default package in a directory named <span class="emphasis"><em>generated</em></span>. You can control the package name with the <a id="I_indexterm24_id836471" class="indexterm"/><code class="literal">-p</code> switch and the directory with <a id="I_indexterm24_id836484" class="indexterm"/><code class="literal">-d</code>. See the <code class="literal">xjc</code> documentation for more options.</p><p>Studying the generated classes will give you some hints as to how many annotations are used, although <code class="literal">xjc</code> is a little more verbose than it has to be. Also note that <code class="literal">xjc</code> produces a class called <code class="literal">ObjectFactory</code> that contains factory methods for each type, such as <code class="literal">createInventory()</code> and <code class="literal">createAnimal()</code>. If you look at these methods, you’ll see that they really just call <code class="literal">new</code> on the plain Java objects and they seem superfluous. The <code class="literal">ObjectFactory</code> is mainly there for legacy reasons. In ealier versions of JAXB, before annotations, the generated classes were not as simple to construct. Additionally, the <code class="literal">ObjectFactory</code> contains a helper method to create a <code class="literal">JAXBElement</code> type, which may be useful in special situations. For the most part, you can ignore these.<a id="I_indexterm24_id836559" class="indexterm"/><a id="I_indexterm24_id836566" class="indexterm"/></p></div><div class="sect2" title="Generating an XML Schema from a Java Model"><div class="titlepage"><div><div><h2 class="title"><a id="id2017784"/>Generating an XML Schema from a Java Model</h2></div></div></div><p><a id="I_indexterm24_id836578" class="indexterm"/> <a id="I_indexterm24_id836588" class="indexterm"/>You can also generate an XML Schema directly from your annotated Java classes using the JAXB XML Schema binding generator: <a id="I_indexterm24_id836600" class="indexterm"/><code class="literal">schemagen</code>. The <code class="literal">schemagen</code> command-line tool comes with the JDK. It can generate a schema starting with Java source or class files. Use the <code class="literal">-classpath</code> argument to specify the location of the classes or source files and then provide the name of the root class in your hierarchy:</p><a id="I_programlisting24_id836624"/><pre class="programlisting"><code class="n">schemagen</code> <code class="o">-</code><code class="n">classpath</code> <code class="o">.</code> <code class="n">Inventory</code></pre><p>Having worked our way through the options for bridging XML to Java, we’ll now turn our attention to transformations on XML itself with XSL, the styling language for XML.</p></div></div></body></html>