users@jaxb.java.net

Re: How can I unmarshall a xsd:any element ?

From: Aleksei Valikov <valikov_at_gmx.net>
Date: Fri, 28 Sep 2007 12:16:44 +0200

Hi.

> I am encountering the same problem.

Everything's almost fine. Use xsd:any with processContents="lax" or
"strict" and you'll get your generic objects unmarshalled in the
appropriate property. This will be JAXBElement encapsulating the real
value.

> How can I also mashall an object in the list of generic object?

Just normally. Either pass it directly to the marshaller or wrap it in
a JAXBElement.

> I have tried mashalling a string encapsulating it in a JAXBElement.
> Is it correct?

It is hard to say w/o seeing what you actually do.

> Anyway the unmarhaller does no t work!!!
> I get the object that is a xerces NMElement, but I an not able to recover
> the class inside this element.

If you have a lax xsd:any, this may happen in case JAXB could not
parse the contents of the xsd:any. Are you sure you have a declared
global element in your schema that you put into xsd:any as content?
NMElement is probably a concrete implementation of DOM Element from
Xerces.

> > I have a xsd:any element (vendorExtensions) that I would like to
> > unmarshall but I don't know how to do it. Do I have to create another
> > JAXBContext object ?

No, this is typically not necessary.

> > The file generated with JAXB from this xsd type
> >
> >
> > <xsd:complexType name="MDVendorExtensions_T">
> > <xsd:sequence>
> > <xsd:any namespace="##any" processContents="lax" minOccurs="0"
> > maxOccurs="unbounded"/>
> > </xsd:sequence>
> > </xsd:complexType>

Some ISO 19115 or similar? :)
- Show quoted text -

> > is :
> >
> >
> > @XmlAccessorType(XmlAccessType.FIELD)
> > @XmlType(name = "MDVendorExtensions_T", propOrder = {
> > "any"
> > })
> > public class MDVendorExtensionsT {
> >
> > @XmlAnyElement(lax = true)
> > protected List any;
> > ...
> > }
> >
> >
> > Here is a test file :
> >
> > public class UnmarshalRead {
> >
> > public static void main( String[] args ) {
> > try {
> > // create a JAXBContext capable of handling classes generated
> > into
> > // the primer.po package
> > JAXBContext jc = JAXBContext.newInstance( "primer.po" );
> >
> > // create an Unmarshaller
> > Unmarshaller u = jc.createUnmarshaller();
> >
> > // unmarshal a po instance document into a tree of Java
> > content
> > // objects composed of classes from the primer.po package.
> > JAXBElement<?> poElement = (JAXBElement<?>)u.unmarshal( new
> > File("po.xml" ) );
> > PurchaseOrderType po =
> > (PurchaseOrderType)poElement.getValue();
> >
> > MDVendorExtensionsT vendorExtension = (MDVendorExtensionsT)
> > poElement.getValue();
> > // how can I unmarshall vendorExtension ??

Something like ((JAXBElement) vendorExtension.getAny().get(0)).getValue().

> >
> > }
> > }


I guess you guys just have some problems with schemas. Take a look at
this simple schema fragment:

       <xsd:element name="anyCollectionStrict" type="test:AnyCollectionStrict"/>
       <xsd:complexType name="AnyCollectionStrict">
               <xsd:sequence>
                       <xsd:any namespace="##any"
processContents="strict" minOccurs="0"
maxOccurs="unbounded"/>
               </xsd:sequence>
       </xsd:complexType>

       <xsd:element name="anyCollectionLax" type="test:AnyCollectionLax"/>
       <xsd:complexType name="AnyCollectionLax">
               <xsd:sequence>
                       <xsd:any namespace="##any"
processContents="lax" minOccurs="0"
maxOccurs="unbounded"/>
               </xsd:sequence>
       </xsd:complexType>

And this XML:


<test:anyCollectionStrict xmlns:test="urn:test">
       <test:anyCollectionLax>
               <p>test</p>
       </test:anyCollectionLax>
</test:anyCollectionStrict>

When you unmarshall this, you'll get JAXBElement with value AnyCollectionStrict.
This value has getAny() - a list consisting of a single JAXBElement
with a value of AnyCollectionLax.
This value has getAny() - a list consisting of a single DOM element
(<p>test</p>).

Bye.
/lexi