Search code examples
javaxmlxstream

in Java Xstream how to change alias inside an object?


I'm serializing a very simple graph into an XML using xStream, I have this output which is pretty close from what I want:

<grafo>
  <nodo id="1">
   <nodo id="2"/>
  </nodo>
  <nodo id="2">
    <nodo id="3"/>
    <nodo id="4"/>
  </nodo>
  <nodo id="3">
    <nodo id="5"/>
  </nodo>
  <nodo id="4">
    <nodo id="6"/>
  </nodo>
 </grafo>

But I need in the output that every node inside another node (an edge) to appear with the alias "child" and not with "nodo".


Solution

  • I do not believe you can do this with simple aliases. But you can do it with a custom serializer like below. The xstream doc has a good converter tutorial which includes details on how to register a custom converter.

    public class Nodo {
      String id;
      ArrayList<Nodo> children = new ArrayList<>();
    }
    
    public class NodoConverter implements Converter {
    
    
      /** {@inheritDoc} */
      @Override
      public boolean canConvert(Class arg0) {
        return arg0.equals(Nodo.class);
      }
    
      /** {@inheritDoc} */
      @Override
      public void marshal(Object arg0, HierarchicalStreamWriter writer, MarshallingContext arg2) {
        marshal((Nodo) arg0, writer, arg2, "nodo");
      }
    
      private void marshal(Nodo nodo, HierarchicalStreamWriter writer, MarshallingContext ctx, String elname) {
        writer.addAttribute("id", nodo.getId());
        for (Nodo child : nodo.children) {
          writer.startNode("child");
          ctx.convertAnother(child);
          writer.endNode();
        }
      }
    
      /** {@inheritDoc} */
      @Override
      public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext ctx) {
        Nodo nodo = new Nodo();
        nodo.setId(reader.getAttribute("id"));
        while (reader.hasMoreChildren()) {
          reader.moveDown();
          Nodo child = (Nodo) ctx.convertAnother(nodo, Nodo.class);
          nodo.children.add(child);
          reader.moveUp();
        }
      }
    
    }