2

I'm currently working on marshalling/unmarshalling XML messages. Here are my two XML elements :

@XmlRootElement(namespace = "http://namespaceA")
public class RootElementA {

    @XmlElement
    private ElementXX elementXX;

}

@XmlRootElement(namespace = "http://namespaceB")
public class RootElementB {

    @XmlElement
    private ElementXX elementXX;

}

When unmarshalling a RootElementB I have the following error :

javax.xml.bind.UnmarshalException: unexpected element (uri:"http://namespaceB", local:"ElementXX"). Expected elements are <{}ElementXX>

If I add the namespace to the ElementXX declaration, I have the same error except that it occurs for properties of ElementXX.

The problem is that I can't set the namespace on properties of ElementXX because it is specified in both namespaces and I don't want to duplicate my class just to change the namespace...

Do you have an idea ? Thanks.

EDIT

Here is a XML sample :

<RootElementA xmlns="http://namespaceA">
    <ElementXX>
        <name>blabla</name>
        <desc>blabla</desc>
    </ElementXX>
</RootElementA>

If I don't set a namespace to ElementXX in XmlRootElementA class I have the error above. If I set it, I have the same error but for the name property.

c4k
  • 4,270
  • 4
  • 40
  • 65

3 Answers3

1

You can remove the @XmlElement annotation for ElementXX. As long as it has a public getter, default behavior is to marshal it as well.

The XML should then look like this.

<ns3:rootElementB xmlns:ns2="http://namespaceA" xmlns:ns3="http://namespaceB">
    <elementXX/>
</ns3:rootElementB>

An alternative is to declare the namespace of ElementXX in its java class using @XmlRootElement similar to RootElementA and B. Then replacing @XmlElement with @XmlElementRef in RootElementA and B.

XML would then look like this: (Note: I added the field name for the test)

<ns4:rootElementB xmlns:ns2="http://namespaceXX" xmlns:ns3="http://namespaceA" xmlns:ns4="http://namespaceB">
    <ns2:elementXX>
        <name>test</name>
    </ns2:elementXX>
</ns4:rootElementB>

I was not able to exactly reproduce your error. I think, however, that having ElementXX declared in two namespaces is not advisable, to say the least. If you can modify your Schemas, I suggest creating a new one with its own namespace and declaring ElementXX in it. Then modify the other two to reference its elements.

W Almir
  • 656
  • 8
  • 19
  • "I think, however, that having ElementXX declared in two namespaces is not advisable" : totally agree with you but I'm using schemas for an external API, I can't modify them. In fact I'd like to use ElementXX of namespace A in RootElementA and ElementXX of namespace B in RootElementB, without having to specify the namespace in the declaration. Is that possible ? – c4k Sep 03 '13 at 12:26
0

you didnt have xml here to have a look.. but i guess the below link will give you an answer.

XML unmarshalling using Jaxb with namespaces and schema

if not post the xml you are trying to unmarshall.

Community
  • 1
  • 1
pappu_kutty
  • 2,378
  • 8
  • 49
  • 93
  • I updated my question with the XML. The XML is coming from an external API so I can't edit it before unmarshalling (didn't find an answer in your link). – c4k Sep 03 '13 at 14:55
0

You can use the @XmlSchema annotation to specify the namespace qualification for classes and properties within a package. You can specify the namespace for the properties of a class by specifying the namespace on @XmlType. Then you can specify the namespace for a so single element/attribute using @XmlRootElement, @XmlElement, and @XmlAttribute.

For More Information

bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • Thanks for the link, very helpful but not for my problem here ;) The main problem is that if I set namespaceB to ElementXX in RootElementB, I have the error above for the elements inside ElementXX... And I can't set any namespace in ElementXX as my class is the mapping for an XML element present in namespaceA and namespaceB... I'd like to specify that when adding ElementXX in RootElementA use namespaceA, and when adding in RootElementB use namespaceB – c4k Sep 03 '13 at 12:42
  • @Chafik - There are 2 distinct `elementXX` properties so that is handled using one of the mechanisms I pointed out. The real issue here is how to handle the instance of `ElementXX` correct? – bdoughan Sep 03 '13 at 12:45
  • Exactly. I don't want to manage two classes ElementXX that are exactly the same, except the namespace – c4k Sep 03 '13 at 12:55
  • @Chafik - How much of the model is the same for the two different namespaces? – bdoughan Sep 03 '13 at 12:57
  • More or less 60 and the other problem is that I have factories that fill my objects with application related data. For example the ElementXXFactory will have a ElementXX property and some other properties related to my application model. In this factory I fill the properties of elementXX with the data loaded from the database. If I have to keep two classes of ElementXX, I'll have to develop two factories or make each ElementXX implement ElementXXInterface and use it in my factory... Hard job for just a problem of namespaces :/ – c4k Sep 03 '13 at 13:06