Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » xsi:type with namespace using MOXy
xsi:type with namespace using MOXy [message #1043581] Wed, 17 April 2013 22:27 Go to next message
M Fischer is currently offline M FischerFriend
Messages: 2
Registered: April 2013
Junior Member
We are using MOXy with an external binding file to marshal and unmarshal some XML from an external source. The XML has elements that use xsi:type with the type having a namespace, i.e. xsi:type="ns:Type". We can unmarshal them if we take off the namespace, i.e. xsi:type="type". How can we do this with the namespace on?
Re: xsi:type with namespace using MOXy [message #1044196 is a reply to message #1043581] Thu, 18 April 2013 15:50 Go to previous messageGo to next message
Denise Smith is currently offline Denise SmithFriend
Messages: 11
Registered: July 2009
Junior Member
Hi,

Can you post some more information that shows the xml/model files/external bindings file and how you create the JAXBContext. What happens when the xsi:type="ns:Type" - do you get an exception? If you do post the stacktrace. If you remove the external bindings file does that change the outcome? If you build an instance of your model and marshal it out that will show what MOXy is expecting in terms of the mappings you have. Also what version of eclipselink are you using?

Denise
Re: xsi:type with namespace using MOXy [message #1044267 is a reply to message #1043581] Thu, 18 April 2013 17:36 Go to previous messageGo to next message
M Fischer is currently offline M FischerFriend
Messages: 2
Registered: April 2013
Junior Member
Denise, thanks for the reply. We are using version 2.4.0. Here's some more information.

Here's an example of what we're seeing:

XML:
<?xml version="1.0" encoding="UTF-8"?>
<MyContainer xmlns:xsi="hxxp://www.w3.org/2001/XMLSchema-instance">
    <aaa xsi:type="bbB" name="foo" attrFromB="bar" />
    <aaa xsi:type="ccC" name="foo" attrFromC="bar" />
</MyContainer>


Class BbB:
package com.example.model;

public class BbB extends AaA{
   private String attrFromB;

   public String getAttrFromB()   {
      return attrFromB;
   }

   public void setAttrFromB(String value)   {
      attrFromB = value;
   }
}


Binding:
<?xml version="1.0"?>
<xml-bindings xmlns="hxxp://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="com.example.model">
    <xml-schema>
        <xml-ns prefix="xsi" namespace-uri="hxxp://www.w3.org/2001/XMLSchema-instance" />
    </xml-schema>
    <java-types>
        <java-type name="BbB" xml-accessor-type="NONE">
            <java-attributes>
                <xml-attribute java-attribute="attrFromB" />
            </java-attributes>
        </java-type>
        <java-type name="CcC" xml-accessor-type="NONE">
            <java-attributes>
                <xml-attribute java-attribute="attrFromC" />
            </java-attributes>
        </java-type>
        <java-type name="MyContainerClass" xml-accessor-type="NONE">
            <xml-root-element name="MyContainer" />
            <java-attributes>
                <xml-element java-attribute="bbb" xml-path="aaa[@xsi:type='bbB'])" />
                <xml-element java-attribute="ccc" xml-path="aaa[@xsi:type='ccC'])" />
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>


Java:
   public static void main(String[] args) throws Exception
   {
      Map<String, Object> properties = new HashMap<String, Object>(1);
      properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "testBinding.xml");
      
      JAXBContext jc = JAXBContext.newInstance(new Class[] { MyContainerClass.class }, properties);
      Unmarshaller unmarshaller = jc.createUnmarshaller();
      
      InputStream isa = TestDemo.class.getClassLoader().getResourceAsStream("testDemo.xml");
      
      MyContainerClass container = (MyContainerClass) unmarshaller.unmarshal(isa);
      
      Marshaller marshaller = jc.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      marshaller.marshal(container, System.out);

   }


That all works fine.

However, our data comes in with a namespace on the xsi:type, so something like:
<?xml version="1.0" encoding="UTF-8"?>
<MyContainer xmlns:xsi="hxxp://www.w3.org/2001/XMLSchema-instance" xmlns:ns1="hxxp://www.model.example.com">
    <aaa xsi:type="ns1:BbBType" name="foo" attrFromB="bar" />
    <aaa xsi:type="ns1:CcCType" name="foo" attrFromC="bar" />
</MyContainer>


When we update the binding for that xml-path, it throws this exception:
Exception in thread "main" javax.xml.bind.UnmarshalException
 - with linked exception:
[Exception [EclipseLink-43] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [ns1:BbBType] of type [class java.lang.String].
Descriptor: XMLDescriptor(com.example.model.BbB --> [])]
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:158)
    at com.example.test.TestDemo.main(TestDemo.java:29)
Caused by: Exception [EclipseLink-43] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class for indicator field value [ns1:BbBType] of type [class java.lang.String].
Descriptor: XMLDescriptor(com.example.model.BbB --> [])
    at org.eclipse.persistence.exceptions.DescriptorException.missingClassForIndicatorFieldValue(DescriptorException.java:937)
    at org.eclipse.persistence.internal.oxm.QNameInheritancePolicy.classFromRow(QNameInheritancePolicy.java:199)
    at org.eclipse.persistence.internal.oxm.XMLRelationshipMappingNodeValue.processChild(XMLRelationshipMappingNodeValue.java:61)
    at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.startElement(XMLCompositeObjectMappingNodeValue.java:323)
    at org.eclipse.persistence.oxm.record.UnmarshalRecord.startElement(UnmarshalRecord.java:783)
    at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parseEvent(XMLStreamReaderReader.java:114)
    at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:83)
    at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:72)
    at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:794)
    at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:660)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:526)
    at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:149)
    ... 1 more


Creating an object and marshaling it with the namespaced xsi:type writes out correctly (the xml sample above). Any guidance you can provide is appreciated.

[Updated on: Thu, 18 April 2013 17:38]

Report message to a moderator

Re: xsi:type with namespace using MOXy [message #1044359 is a reply to message #1044267] Thu, 18 April 2013 20:31 Go to previous messageGo to next message
Denise Smith is currently offline Denise SmithFriend
Messages: 11
Registered: July 2009
Junior Member
If you want BbB and CcC to exist in a given namespace you can specify the namespace attribute on the xml-type element in the bindings file. So in your bindings file if you added the following then you would be able to unmarshal the xml document with namespaces. To be clear now this won't unmarshal the document you originally posted (no namespaces).

  
      <java-type name="BbB" xml-accessor-type="NONE">
         <xml-type namespace="hxxp://www.model.example.com"/>
         <java-attributes>
...
      <java-type name="CcC" xml-accessor-type="NONE">
         <xml-type namespace="hxxp://www.model.example.com"/>


The catch with this is that now the xml-paths in the bindings file are not correct and they would need to be something like the following
      <xml-element java-attribute="bbb" xml-path="aaa[@xsi:type='ns1:bbB'])" />
      <xml-element java-attribute="ccc" xml-path="aaa[@xsi:type='ns1:ccC'])" />

but right now MOXy does not handle namespaces in the values of the xml-paths. ie: the xml-path would match when the docs had xsi:type='ns1:bbB' but if a different doc used a different prefix for the same namespace and had xsi:type='ns2:bbB' that would not get put in the BbB collection. You could open an enhancement request for MOXy to support namespaces in the value or perhaps we can find an alternate solution for breaking up the collections by subclass.

Denise
Re: xsi:type with namespace using MOXy [message #1044587 is a reply to message #1044359] Fri, 19 April 2013 05:06 Go to previous message
Blaise Doughan is currently offline Blaise DoughanFriend
Messages: 163
Registered: July 2009
Senior Member

I have opened the following enhancement request for this:
- http://bugs.eclipse.org/406041

[Updated on: Fri, 19 April 2013 05:23]

Report message to a moderator

Previous Topic:JPA with extended objects
Next Topic:DBWS / NamingConventionTransformer
Goto Forum:
  


Current Time: Wed Nov 26 10:32:38 GMT 2014

Powered by FUDForum. Page generated in 0.02994 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software