3

)

I have an xmlelement which can be from different Types. Independent of the type it has the same name. It can be an object or just a reference via URI to an existing object. I thought xmlElements could be the solution. Marshalling works fine but by unmarshalling it, it chooses everytime the last given class type.

The Class Flower which contains the Element

@XmlRootElement(name = "Flower")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "id", "name", "refName", "description", "created", "updated", "color",
    "seed")
public class Flower extends CommonElements{

private string color;
@XmlElements({
    @XmlElement(name="seed", type=Seed.class),
    @XmlElement(name="seed", type=Reference.class)  
})
public Object seed;

}

The class seed which is one of the Types the element can contain

@XmlRootElement(name = "Seed")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "id", "name", "refName", "description", "created", "updated",
    "category", "country"})
public class Seed extends CommonElements{

protected String category = "";
protected String country = "";

}

And the other class which can be contained by the element

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
public class Reference {
@XmlAttribute(name="href")
protected URI href;
}

In CommonElements are just some generic elements like id, refName, description etc.. The XML can look like

<Flower>
    <id>http://localhost/test/flowers/1</id>
    <refName>redRose</refName>
    <description>classical red rose </description>
    <color>red</color>
    <seed href="http://localhost/test/seeds/1" />
</Flower>

Or like

<Flower>
   <id>http://localhost/test/flowers/1</id>
   <refName>redRose</refName>
   <description>classical red rose </description>
   <color>red</color>
   <seed>
      <id>http://localhost/test/seeds/1</id>
      <refName>wildrose</refName>
      <description>Special Seed for beautiful wild roses</description>
      <category>wildrose</category>
      <country>china</country>
  </seed>
</Flower>

I assumed that the different structure of the classes are enough for jaxb to distinguish the objects. I am afraid I have to use adapters but I hope someone has another great idea.

I know there is one Topic similiar to mine. But the types in the topic looks alike so jaxb can't distinguish them. (JAXB @XmlElements, different types but same name?)

Thanks and sorry for my bad english.

Edit: Is there a way to add the type by marshalling, that jaxb knows exactly which type it is for unmarshalling?

dan1st
  • 12,568
  • 8
  • 34
  • 67
nsrlady
  • 105
  • 1
  • 6

1 Answers1

0

You cannot have same name inside the @XmlElements. The code won't compile. You can use the @XmlSeeAlso but it is not correct way to do it. @XmlSeeAlso is meant for subclasses but in this case it will work.

This solution will workout only if you know the type of classes set in the

flower.object

@XmlRootElement(name = "Flower")
@XmlSeeAlso({Seed.class,Reference.class})
@XmlAccessorType(XmlAccessType.FIELD)
public class Flower extends CommonElements {
    public Flower(){}

    public Flower(String id, String name){
        super(id,name);
    }
    @XmlAttribute
    private String color;
    @XmlElement
    public Object seed;

    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
}

<Flower>
    <id>2</id>
    <refName>redRose</refName>
    <color>RED</color>
    <seed xsi:type="seed" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <id>1</id>
        <refName>wildrose</refName>
        <category></category>
        <country>USA</country>
    </seed>
</Flower>

<Flower>
    <id>3</id>
    <refName>whiteRose</refName>
    <color>white</color>
    <seed xsi:type="reference" href="www.google.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</Flower>
Chandru
  • 964
  • 11
  • 16
  • mhm.. the same name compiled and marshalled perfect. But Your solution works fine. Like u said xmlseealso is meant for something else.. so it seems to be a bit dirty.. but as long as it works, its fine for me. :) – nsrlady Apr 29 '13 at 14:01
  • strange. for me in eclipse juno with JDK6 it is giving compilation error. – Chandru May 07 '13 at 06:36
  • mhm.. now I get [com.sun.istack.internal.SAXException2: Instance of "Seed" is substituting "java.lang.Object", but "Seed" is bound to an anonymous type.] – nsrlady May 14 '13 at 08:57
  • I got the Error because I had in my Seed.class @XmlType(name="").. now the error makes sense ;) – nsrlady May 14 '13 at 11:33