Wrong marshalling of xsd:any type

View: New views
2 Messages — Rating Filter:   Alert me  

Wrong marshalling of xsd:any type

by Florian Huonder-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.

Hi all,

 

I have the following schema fragment:

 

<complexType name="StatusDetailType">

   <complexContent>

     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">

       <sequence>

         <any/>

       </sequence>

     </restriction>

   </complexContent>

 </complexType>

 

 

The corresponding java class looks like this:

 

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "StatusDetailType", propOrder = {

    "content"

})

public class StatusDetailType

    implements Serializable

{

 

    private final static long serialVersionUID = 632768732L;

   

    @XmlAnyElement(lax = true)

    protected List<Object> content;

 

    public List<Object> getContent() {

        if (content == null) {

            content = new ArrayList<Object>();

        }

        return this.content;

    }

}

 

A type that can be placed into the any attribute is e.g. the MissingAttributeDetailType.

Schema of this type looks like:

<complexType name="MissingAttributeDetailType">
   <complexContent>
     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
       <sequence>
         <element ref="{urn:oasis:names:tc:xacml:2.0:context:schema:os}AttributeValue" maxOccurs="unbounded" minOccurs="0"/>
       </sequence>
       <attribute name="AttributeId" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
       <attribute name="DataType" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
       <attribute name="Issuer" type="{http://www.w3.org/2001/XMLSchema}string" />
     </restriction>
   </complexContent>
 </complexType>

 

And the corresponding java class is:

@XmlRootElement

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "MissingAttributeDetailType", propOrder = { "attributeValues" })

public class MissingAttributeDetailType implements Serializable {

 

      private final static long serialVersionUID = 632768732L;

      @XmlElement(name = "AttributeValue")

      protected List<AttributeValueType> attributeValues;

      @XmlAttribute(name = "AttributeId", required = true)

      @XmlSchemaType(name = "anyURI")

      protected String attributeId;

      @XmlAttribute(name = "DataType", required = true)

      @XmlJavaTypeAdapter(URNToDataTypeConverter.class)

      @XmlSchemaType(name = "anyURI")

      protected DataTypeAttribute<?> dataType;

      @XmlAttribute(name = "Issuer")

      protected String issuer;

 

 

}

 

Now when I marshall the StatusDetailType class this results in:

<StatusDetail>

    <missingAttributeDetailType DataType="http://www.w3.org/2001/XMLSchema#string" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"/>

</StatusDetail>

 

But this is wrong because it should marshallt to:

<StatusDetail>

    <MissingAttributeDetail DataType="http://www.w3.org/2001/XMLSchema#string" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"/>

</StatusDetail>

 

 

I use JAXB 2.1.12.

A second question: Why is the @XmlRootElement needed in the MissingAttributeDetailType class? Without it, there is an exception asking for this annotation.

 

I hope somebody can help me.

Thanks a lot in advance.

 

Regards

Florian


Re: Wrong marshalling of xsd:any type

by Wolfgang Laun-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The exact Java representation of StatusDetailType need not have a List<Object> since <any/> does not have maxOccurs /= 1.

Answer #1:
In the Java code, there is no explicit information about the XML element tag to use for an element of schema type
MissingAttributeDetailType. You must have prepared a document by

StatusDetailType sd = ...;
MissingAttributeDetailType mad = ...;
sd.getContent().add( mad );

Thus, the only information for the marshaller about the XML element to take the place of the <any/> wildcard is object mad's class, which happens to be
MissingAttributeDetailType.

To get the correct XML element tag, you must create an object of class JAXBElement<
MissingAttributeDetailType> which contains an Object field "value" (set to a MissingAttributeDetailType, defining all the children of the element), and a
javax.xml.namespace.QName field "name" defining the tag's namespace and local name.

The easiest way for obtaining code creating the JAXBElement<?> would be to xjc-compile the schema with the complex types and an additional
  <xs:element name="MissingAttributeDetail" type="MissingAttributeDetailType"/>
The ObjectFactory.java contains a suitable method createMissingAttributeDetail(...)

Or see https://jaxb.dev.java.net/tutorial/section_4_5-Calling-marshal.html
the method wrap to create an arbitrary JAXBElement.

Answer #2:
Then, you won't need @XmlRootElement for class
MissingAttributeDetailType any more, because, being wrapped in an JAXBElement object, it won't be a class for a "root" element any more.

-W

On Tue, Nov 3, 2009 at 5:53 PM, Florian Huonder <fhuonder@...> wrote:

Hi all,

 

I have the following schema fragment:

 

<complexType name="StatusDetailType">

   <complexContent>

     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">

       <sequence>

         <any/>

       </sequence>

     </restriction>

   </complexContent>

 </complexType>

 

 

The corresponding java class looks like this:

 

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "StatusDetailType", propOrder = {

    "content"

})

public class StatusDetailType

    implements Serializable

{

 

    private final static long serialVersionUID = 632768732L;

   

    @XmlAnyElement(lax = true)

    protected List<Object> content;

 

    public List<Object> getContent() {

        if (content == null) {

            content = new ArrayList<Object>();

        }

        return this.content;

    }

}

 

A type that can be placed into the any attribute is e.g. the MissingAttributeDetailType.

Schema of this type looks like:

<complexType name="MissingAttributeDetailType">
   <complexContent>
     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
       <sequence>
         <element ref="{urn:oasis:names:tc:xacml:2.0:context:schema:os}AttributeValue" maxOccurs="unbounded" minOccurs="0"/>
       </sequence>
       <attribute name="AttributeId" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
       <attribute name="DataType" use="required" type="{http://www.w3.org/2001/XMLSchema}anyURI" />
       <attribute name="Issuer" type="{http://www.w3.org/2001/XMLSchema}string" />
     </restriction>
   </complexContent>
 </complexType>

 

And the corresponding java class is:

@XmlRootElement

@XmlAccessorType(XmlAccessType.FIELD)

@XmlType(name = "MissingAttributeDetailType", propOrder = { "attributeValues" })

public class MissingAttributeDetailType implements Serializable {

 

      private final static long serialVersionUID = 632768732L;

      @XmlElement(name = "AttributeValue")

      protected List<AttributeValueType> attributeValues;

      @XmlAttribute(name = "AttributeId", required = true)

      @XmlSchemaType(name = "anyURI")

      protected String attributeId;

      @XmlAttribute(name = "DataType", required = true)

      @XmlJavaTypeAdapter(URNToDataTypeConverter.class)

      @XmlSchemaType(name = "anyURI")

      protected DataTypeAttribute<?> dataType;

      @XmlAttribute(name = "Issuer")

      protected String issuer;

 

 

}

 

Now when I marshall the StatusDetailType class this results in:

<StatusDetail>

    <missingAttributeDetailType DataType="http://www.w3.org/2001/XMLSchema#string" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"/>

</StatusDetail>

 

But this is wrong because it should marshallt to:

<StatusDetail>

    <MissingAttributeDetail DataType="http://www.w3.org/2001/XMLSchema#string" AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id"/>

</StatusDetail>

 

 

I use JAXB 2.1.12.

A second question: Why is the @XmlRootElement needed in the MissingAttributeDetailType class? Without it, there is an exception asking for this annotation.

 

I hope somebody can help me.

Thanks a lot in advance.

 

Regards

Florian