Search code examples
javaxmlxstream

XStream, Aliasing and "DuplicateFieldException"


I'm trying to write an app so that it is able to read this kind of XML and create an entire object based on it;

<actor id="id273211" PGFVersion="0.19" GSCVersion="0.10.4">
  <attributes>
    <text id="name">Actor 1b</text>
    <point id="position">
      <real id="x">0</real>
      <real id="y">0</real>
    </point>
  </attributes>
</actor>

My problem is I'm aliasing members of the class Point as "real" and it gives an exception.

What I have now is;

@XStreamAlias("actor")
public class Actor {

    @XStreamAsAttribute
    String id = "",PGFVersion = "", GSCVersion = "";
    Attributes attributes = new Attributes();
}


public class Attributes {

    public Text text = new Text("name", "Actor 1");
    public Point point = new Point();

}


@XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"})
@XStreamAlias("text")
public class Text {

    @XStreamAsAttribute
    String id;

    String value;

    public Text(String text, String value) {
        this.id = text;
        this.value = value;
    }


public class Point {
     @XStreamAlias("real")
     public Real x = new Real("x", "11");
     @XStreamAlias("real") 
     public Real y = new Real("y", "21");
     @XStreamAsAttribute
     public String id = "position";

}

And my Test.java:

public static void main(String[] args) throws Exception {

    XStream xstream = new XStream();

    Actor actor2 = new Actor();

    xstream.processAnnotations(Text.class);
    xstream.processAnnotations(Real.class);
    xstream.processAnnotations(Point.class);
    xstream.processAnnotations(Actor.class);

    String xml = xstream.toXML(actor2);

    System.out.println(xml);

}

This outputs XML perfectly, as follows:

<actor id="" PGFVersion="" GSCVersion="">
  <attributes>
    <text id="name">Actor 1</text>
    <point id="position">
      <real id="x">11</real>
      <real id="y">21</real>
    </point>
  </attributes>
</actor>

But when I try to import it using:

String xml = xstream.toXML(actor2);

Actor actorNew = (Actor)xstream.fromXML(xml);
System.out.println(xml);

It gives an exception:

Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field y ---- Debugging information ---- field : y class : projectmerger1.Point required-type : projectmerger1.Point converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter path : /projectmerger1.Actor/attributes/point/real[2] line number : 6 class[1] : projectmerger1.Attributes class[2] : projectmerger1.Actor

version : 1.4.6

Is this a wrong setup as a whole or can I continue using it with some tweaks?


Solution

  • I solved it by changing in Point class;

    public class Point {
        /*
         @XStreamAlias("real")
         @XStreamAlias("real2") 
         public Real y = new Real("y", "21");
         @XStreamAsAttribute
         public String id = "position";
         */
    
        @XStreamImplicit
         public List xy = new ArrayList();
    
    
         public void add(Real entry) {
                    xy.add(entry);
            }
    
    }
    

    and adding this to my Test.java:

        actor2.attributes.point.add(new Real("x","0"));
        actor2.attributes.point.add(new Real("y","0"));
    

    I'll keep experimenting with this. Thanks for the support.