Search code examples
javaxmlxstream

XStream Serialize a class to XML using an attribute field as attribute for XML tag of another field


i have this class

public class EventXML{
    private String name;
    private String ip;
    private Date date;
    private String dateFormat;
    private String eventName;
}

using this function:

public String toXML(){
        String x;
        XStream xs = new XStream();
        x = xs.toXML(this);
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+x;
    }

i get this result:

<?xml version="1.0" encoding="UTF-8"?>
    <EventXML>
      <name>SuperFarmer</name>
      <ip>IPPPPPPP</ip>
      <myData>2018-05-15 12:48:05.343 UTC</myData>
      <dateFormat>HH:mm:ss dd/MM/yyyy</dateFormat>
      <eventName>CLICCA</eventName>
    </EventXML>

but i would like an XML like this:

<?xml version="1.0" encoding="UTF-8"?>
<EventXML>
  <name>SuperFarmer</name>
  <ip>IPPPPPPP</ip>
  <myData dateFormat="HH:mm:ss dd/MM/yyyy">12:48:05 15/05/2018</myData>
  <eventName>CLICCA</eventName>
</EventXML>

could you give me some tips to get my objective?


Solution

  • I was able to reach the desired xml outupt with some changes to the EventXML class. I created an inner class that holds the <myData>element and attribute:

    public class EventXML
    {
        public String name;
        public String ip;
        public MyData myData = new MyData();
        public String eventName;
    
        public static class MyData {
            public Date date;
            public String dateFormat;
        }
    }
    

    now in the serialization method, we tell xstream how to serialize MyData into an xml element and also tell xstream how to convert date fields:

    1. ToAttributedValueConverter accepts a class (first arg) and name of field (last arg) the named field will be used as element's value, and all other fields of the class will be used as attributes

    2. DateConverter is used by xstream to convert Date typed fields I gave it dateFormat as argument.

    this is how it looks:

    public String toXML() {
        String x;
        XStream xs = new XStream();
    
        // the following tell XStream how to craete myData element:
        // the last arg is the field to be used as element value and all other fields are attributes
        xs.registerConverter(new ToAttributedValueConverter(MyData.class, xs.getMapper(), xs.getReflectionProvider(),
            xs.getConverterLookup(), "date"));
        // register date converter according to dateFormat field
        xs.registerConverter(new DateConverter(myData.dateFormat, new String[]{}));
    
        x = xs.toXML(this);
        return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"+x;
    }