Search code examples
javaxml-serializationaliasxstream

Xstream - String array


First things first, I'm no asking for a solution but a way to think.

I got some data that I need to serialize to check out later... I know how to do it.. but the fields names are the problem...

The data structure contains:

Name of the Field
CoordX
CoordY
Value

(There are like.. 20 different fields. I need to check a biiiggggg string log...)

I could use a single String[][] or several Strings[] ... as I said.. the problem is how it appears on the XML...

If I do a single arraylist multidimensional -> [][] I got this

<teste>
      <string-array>
        <string>fieldName</string>
        <string>x</string>
        <string>y</string>
        <string>value</string>
      </string-array>
      <string-array>
        <string>fieldName</string>
        <string>x</string>
        <string>y</string>
        <string>value</string>
      </string-array>
</teste>

And if I do a single string[] I can put the name of the String as the field name

<Fieldname>      
    <string>X</string>
    <string>y</string>
    <string>Value</string>
</Fieldname>

I saw that normal alias is for ALL fields (@XStreamImplicit(itemFieldName="part")) and that don't solve my problem..

It could be worthless if on the other side when I do deserialization, check the log by line and no by field (I know line 1 is field name, line 2 is x..etc)..

So.. what do you guys think?


Solution

  • I usually design serialization depending on the contents of my "fields". Say that your name and value fields are relatively small, you could serialize them as

    <list>
      <field name="foo" cordX="12324" cordY="1324" value="value of field foo" />
      <field name="foo" cordX="12324" cordY="1324" value="value of field foo" />
    </list>
    

    of course, if value is long, then you don't want to serialize it as attribute, but as a regular field value like so:

    <list>
      <field name="foo" cordX="12324" cordY="1324">The long value </field>
      <field name="foo" cordX="12324" cordY="1324">Even longer field value...</field>
    </list>
    

    You can achieve this using XStream like so:

    public class Run {
        public static void main(String[] args) {
            XStream xs = new XStream(new DomDriver());
            xs.processAnnotations(new Class[] { Field.class, Container.class });
            Container c = new Container();
            c.addField("boo", 1,2, "desc");
            c.addField("boo", 1,2, "desc");
            String serialized = xs.toXML(c);
            System.out.println(serialized);
    
            // deserialize
            Container newContainer = (Container) xs.fromXML(serialized);
            if (newContainer.fields.size() != 2) {
                System.out.println("Not deserialized as expected...");
            }
    
            // if you don't want "container"
            xs.alias("mylist", List.class);
            System.out.println(xs.toXML(c.fields));
        }
    }
    

    where you define your Container and Field like so:

    @XStreamAlias("mylistofitems")
    public class Container {
        public List<Field> fields;
    
        public void addField(String name, int x, int y, String desc) {
            if (fields == null) fields = new ArrayList<Field>();
            fields.add(new Field(name, x,y, desc));
    
        }
    }
    
    @XStreamAlias("field")
    public class Field {
        public Field() {}
        public Field(String name, int x, int y, String desc) {
            this.name = name;
            cordX = x;
            cordY = y;
            value = desc;
        }
        @XStreamAsAttribute
        private String name;
        @XStreamAsAttribute
        private int cordX;
        @XStreamAsAttribute
        private int cordY;
        @XStreamAsAttribute
        private String value;
    }
    

    The program gives this output:

    <mylistofitems>
      <fields>
        <field name="boo" cordX="1" cordY="2" value="desc"/>
        <field name="boo" cordX="1" cordY="2" value="desc"/>
      </fields>
    </mylistofitems>
    <mylist>
      <field name="boo" cordX="1" cordY="2" value="desc"/>
      <field name="boo" cordX="1" cordY="2" value="desc"/>
    </mylist>
    

    Hope this helps.