Jaxb experience Tour 2: unmarshal

Source: Internet
Author: User
I studied unmarshal today. To put it bluntly, it is actually an XML document read operation. The following error occurs when the unmarshaller. unmarshal method returns the actual object type. At first, I always thought that an instance of the XML document root element type should be returned. Through instance operations, I found not only that.
Example 1:
XML Schema:
<? XML version = "1.0" encoding = "UTF-8"?>
<XSD: schema xmlns: XSD = "http://www.w3.org/2001/XMLSchema">
<XSD: element name = "book">
<XSD: complextype>
<XSD: sequence>
<XSD: element name = "name" type = "XSD: string"/>
<XSD: element name = "author" type = "XSD: string"/>
<XSD: element name = "ISBN" type = "XSD: int"/>
<XSD: element name = "publisher" type = "XSD: string"/>
<XSD: element name = "edition" type = "XSD: int"/>
<XSD: Element type = "XSD: Double" name = "price"/>
</XSD: sequence>
</XSD: complextype>
</XSD: Element>
</XSD: schema>
Corresponding XML document:
<? XML version = "1.0" encoding = "UTF-8"?>
<Book xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: nonamespaceschemalocation = "src/simple. XSD">
<Name> Hello China </Name>
<Author> Owen </author>
<ISBN> 1860 </ISBN>
<Publisher> objectiva </publisher>
<Edition> 1 </edition>
<Price> 10.0 </price>
</Book>
Resolution class:

/*********************** The code can make sure the root element of XML document automatically
Jaxbcontext context = jaxbcontext. newinstance ("com. objectiva. jaxbtesting. Book ");

Unmarshaller = context. createunmarshaller ();
Object object = unmarshaller. unmarshal (new file ("Simple. xml "));

If (Object instanceof book)
{
System. Out. println (book) object). getname ());
System. Out. println (book) object). getpublisher ());
System. Out. println (book) object). getauthor ());
System. Out. println (book) object). getisbn ());
System. Out. println (book) object). getedition ());
}

**************************************** **************/
In this example, the unmarshalle. unmarshal method returns an actual XML document root element type instance.
Example 2:
XML Schema:
<? XML version = "1.0" encoding = "UTF-8"?>
<XSD: schema xmlns: XSD = "http://www.w3.org/2001/XMLSchema">
<XSD: element name = "book" type = "booktype"> </XSD: Element>
<XSD: complextype name = "booktype">
<XSD: sequence>
<XSD: element name = "name" type = "XSD: string"/>
<XSD: element name = "author" type = "XSD: string"/>
<XSD: element name = "ISBN" type = "XSD: int"/>
<XSD: element name = "publisher" type = "XSD: string"/>
<XSD: element name = "edition" type = "XSD: int"/>
<XSD: Element type = "XSD: Double" name = "price"/>
</XSD: sequence>
</XSD: complextype>
<XSD: element name = "comment" type = "XSD: string"/>
</XSD: schema>
Corresponding XML document:
<? XML version = "1.0" encoding = "UTF-8"?>
<Book xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: nonamespaceschemalocation = "simpletest. XSD">
<Name> valid Java </Name>
<Author> ruly </author>
<ISBN> 10086 </ISBN>
<Publisher> O 'Reily </publisher>
<Edition> 1 </edition>
<Price> 50.0 </price>
</Book>
Resolution class:
/*********************** The code can't make sure the root element of XML document automatically **/

Jaxbcontext context = jaxbcontext. newinstance ("com. objectiva. jaxbtesting. Book ");
Unmarshaller = context. createunmarshaller ();
Object object = unmarshaller. unmarshal (new file ("simpletest. xml "));

System. Out. println (jaxbelement <booktype>) object). getvalue (). getname ());

/*************************************** **********************/
After this example is parsed, an instance of the jaxbelement type is actually returned.
After analysis, we can conclude that in the first example, the jaxb framework can determine the root element of the XML document based on the XML schema, because the root element type instance can be directly returned during parsing. In the second example, the jaxb framework cannot determine the root element of the XML document. Therefore, the jaxbelement type instance can only be returned during parsing. In the first example, @ xmlrootelement (name = "book") anonation can be seen in the generated Java class, but not in the second example. This confirms what the API says:
Note that when the root element name is unknown and the root
Element has@ Xsi: Type, The XML data is unmarshalled
Using that jaxb mapped class as the value ofJAXBElement.

At this point, the unmarshal operation of the XML document is complete, and the content of the XML document has been loaded into the Java object, and the program can directly operate on it.

I have referred to the study (http://weblogs.java.net/blog/kohsuke/archive/2006/03/why_does_jaxb_p.html), to help me understand quite a lot:
Why does jaxb put @ xmlrootelement sometimes but not always?

IsusaninAsked in the jaxb Forum:

When trying to Marshall an object I get this error message:

unable to marshal type "org.blah.MessageType" as an element
because it is missing an @XmlRootElement annotation

If I add the @ xmlrootelement annotation to the messagetype, it works,
But my question is why doesn't the jaxb compiler put this annotation in
Automatically. It's inconvenient because messagetype is automatically
Generated and I don't want to edit it every time I regenerate the Java
Classes.

Is there any better way to resolve this problem?

Xjc does try to put @ xmlrootelement Annotation on a class that we
Generate from a complex type. The exact condition is somewhat uugly,
The basic idea is that if we can statically guarantee that a complex
Type won't be used by multiple different tag names, we put
@ Xmlrootelement. So for example, if the schema is as follows:

 
  &amp;lt;br&amp;gt;&amp;amp;amp;lt;schema&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;amp;amp;lt;element name="foo"&amp;amp;amp;gt;&amp;lt;br&amp;gt;    &amp;amp;amp;lt;complexType&amp;amp;amp;gt;&amp;lt;br&amp;gt;      ...&amp;lt;br&amp;gt;    &amp;amp;amp;lt;/complexType&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;amp;amp;lt;/element&amp;amp;amp;gt;&amp;lt;br&amp;gt;&amp;amp;amp;lt;/schema&amp;amp;amp;gt;&amp;lt;br&amp;gt;
 

Then you 'd get:

@XmlRootElement
class Foo {
...
}

But if the schema is as follows, then xjc can't eliminate
Possibility that your type might be used in other Schemas (that can be
Compiled separately and put together at runtime ):

 
  &amp;lt;br&amp;gt;&amp;amp;amp;lt;schema&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;amp;amp;lt;element name="foo" type="bar" /&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;amp;amp;lt;complexType name="bar" /&amp;amp;amp;gt;&amp;lt;br&amp;gt;&amp;amp;amp;lt;/schema&amp;amp;amp;gt;&amp;lt;br&amp;gt;
 

So you 'd get:

class Bar {
}
class ObjectFactory {
JAXBElement<Bar> createFoo(Bar value) { ... }
}

Now, the crucial part in the above inference done by xjc is that"Your schema might be used by other Schemas that xjc isn't compiling right now".
This is certainly true for some users (and we learned that the hard
Way), but it's also true that for processing users this is too conservative
An assumption. It's often the case that what you are compiling is
Indeed the whole thing, and you want xjc to know that so that it can
Optimize the generated code more aggressively.

Such notion isn' t defined in the spec, but as an experiment we
Have such aggressive optimization mode in xjc, tentatively called
"Simple-minded binding mode". Consider the following schema that uses
This mode (see that<Xjc: simple/>Customization ):

 
  &amp;lt;br&amp;gt;&amp;amp;amp;lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&amp;lt;br&amp;gt;  xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"&amp;lt;br&amp;gt;  jaxb:version="1.0"&amp;lt;br&amp;gt;  xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"&amp;lt;br&amp;gt;  jaxb:extensionBindingPrefixes="xjc"&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;amp;amp;lt;xs:annotation&amp;amp;amp;gt;&amp;lt;br&amp;gt;    &amp;amp;amp;lt;xs:appinfo&amp;amp;amp;gt;&amp;lt;br&amp;gt;      &amp;amp;amp;lt;jaxb:globalBindings&amp;amp;amp;gt;&amp;lt;br&amp;gt;        &amp;amp;amp;lt;xjc:simple /&amp;amp;amp;gt;&amp;lt;br&amp;gt;      &amp;amp;amp;lt;/jaxb:globalBindings&amp;amp;amp;gt;&amp;lt;br&amp;gt;    &amp;amp;amp;lt;/xs:appinfo&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;amp;amp;lt;/xs:annotation&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;lt;br&amp;gt;  &amp;amp;amp;lt;xs:element name="foo" type="bar" /&amp;amp;amp;gt;&amp;lt;br&amp;gt;  &amp;amp;amp;lt;xs:complexType name="bar" /&amp;amp;amp;gt;&amp;lt;br&amp;gt;&amp;amp;amp;lt;/xs:schema&amp;amp;amp;gt;&amp;lt;br&amp;gt;
 

From this you'll getFooClass, since xjc now knows that only one element is usingBar,
And therefore there's no point in having two of them around (I just
Fixed a few issues WRT this, so if you want to try it, wait
Tomorrow and download nightly.) also note that this is an experimental mode and it is subject to change.

Now, that said, there's another way to work around this issue. If all you want is just to have Al an object@ Xmlrootelement, Then you can just do:

marshaller.marshal( new JAXBElement(
new QName("uri","local"), MessageType.class, messageType ));

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.