1

I looking for a Java annotation which does the same like XmlInclude does in C#.

I get a XML structure over a socket. The structure looks like this:

<Answer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <FunctionReturnCode>0</FunctionReturnCode>
    <AnswerObject xsi:type="Status">
       <DoorOpen>79</DoorOpen>
    </AnswerObject>
</Answer>

The corresponding Java Class is defined as follows:

@XmlRootElement(name="Answer")
@XmlType(propOrder = {"functionReturnCode", "answerObject"})
public class Answer 
{
    private Object m_answerObject         = null;
    private long   m_uiFunctionReturnCode = 0;


    @XmlElement(name="FunctionReturnCode")
    public long getFunctionReturnCode(){ return this.m_uiFunctionReturnCode; }
    public void setFunctionReturnCode(long _uiFunctionReturnCode) { this.m_uiFunctionReturnCode = _uiFunctionReturnCode; }

    @XmlElement(name="AnswerObject")
    public Object getAnswerObject() { return this.m_answerObject; }
    public void setAnswerObject(Object _answerObject) { this.m_answerObject = _answerObject;}
}

In C# the class looks something like this:

[XmlInclude(typeof(SelStatus))]

<<< this seems to me the magic point public class Answer : ICloneable

{

    private uint   m_uiFunctionReturnCode  = 0;

    private object m_answerObject          = null;

    .....Setters/Getters here as well
}

The problem is, that "AnswerObject" can be any type of object. In my example "AnswerObject" is an object of type "Status", but it can be as well a string or what ever.

In C# I can use XmlSerializer to de-serialize the XML structure. In Java I use the following :

JAXBContext context = JAXBContext.newInstance(Answer.class);
Unmarshaller unmarschaller = context.createUnmarshaller();

C# and Java (as well) handles strings automatically. But in the case there is another object then a string I can announce C# with XmlInclude other known classes. Is there something similar in Java?

Hackeris
  • 11
  • 2

1 Answers1

0

@XmlElement on a property of type Object is the correct mapping:

@XmlElement(name="AnswerObject")
public Object getAnswerObject() { return this.m_answerObject; }
public void setAnswerObject(Object _answerObject) { this.m_answerObject = _answerObject;}

You will need to make you ensure that your JAXBContext is aware of any possible values for AnswerObject. You can make your JAXBContext are of these classes when you create it:

JAXBContext.newInstance(Answer.class, ValueA.class, ValueB.class);

Or specify them through the @XmlSeeAlso annotation.

@XmlRootElement(name="Answer")
@XmlType(propOrder = {"functionReturnCode", "answerObject"})
@XmlSeeAlso{{ValueA.class, ValueB.class}
public class Answer 
{
    ...
}
bdoughan
  • 147,609
  • 23
  • 300
  • 400
  • The Unmarshaller returns me "ElementNSImpl" in the case the object is neither null nor a string. But I want to have the correctly filled object. Like .NET does :) As I wrote before just string or null is correctly unmarshalled. – Hackeris Apr 01 '11 at 06:27
  • Ok, finally I figured out where the problem was. After adding an event handler to the unmarshaller (with setEventHandler method) I got the following error message. "unrecognized type name: Status. Did you mean status?".....huhh :D SO I added @XmlType(name="Status") to the class and know everything works fine. Thank u Blaise, Your hint was the missing piece I was looking for :) – Hackeris Apr 01 '11 at 08:40