Reputation: 264
I have surely a problem of understanding of Xstream converter.
I have a pretty complex XML coming from legacy back office application and a just want to convert this one into a simpler java class or a Map with Converter.
My XML is like
<root>
<agent>
<id>123456789</id>
<name>GABIN</name>
<forname>Jean</forname>
<unit>
<legacyReference>AA</legacyReference>
<name>SAN ANTONIO</name>
<legacyName>SA</legacyName>
<address>
<number>1</number>
<street>Sesam street</street>
<city>NoWhere</city>
<legacyID>AAZE-56</legacyID>
</address>
<legacyStructurBlablabla>
<type>OFFICE</type>
<data>
<foo>BAR</foo>
</data>
</legacyStructurBlablabla>
<...>
</unit>
<...>
</agent>
</root>
My destination class is very simple
class Agent {
String id;
String name;
String forname;
String unitName;
String unitType;
<...>
}
My main method looks like
xStream = new XStream(new DomDriver());
stream = this.getClass().getClassLoader().getResourceAsStream("data/agent.xml") ;
xStream.alias("root", Map.class);
xStream.alias("agent", Agent.class);
xStream.registerConverter(new ResultConverter());
xStream.registerConverter(new AgentConverter());
xStream.ignoreUnknownElements();
Object obj = xStream.fromXML(stream);
I don't understand how to step down in favor of another converter.
public class ResultConverter implements Converter {
...
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
Map<String, Object> agents = new HashMap<String, Object>();
while( reader.hasMoreChildren() ) {
reader.moveDown();
// HOW I DO TO STEP DOWN IN FAVOR OF Agent CONVERTER ?
reader.moveUp();
}
return agents;
}
I didn't see Xstream scrolled dow the thierarchy to activate my AgentConverter.
I surely missing the point
EDIT
Xstream may be not thr right tool for this. I would use xmlbeam, according to Cfx advise. XMLBeam projects the XML to a Java Class according to XPATH mapping.
Upvotes: 1
Views: 932
Reputation: 2312
Seems that you want the xml structure not to be reflected in your Java class. If you stick to XStream, I have no solution. But there is an alternative framework that was made to solve exactly this issue. It uses annotations, but IMHO does not violate the KISS principle. Here is an example:
public interface Agent {
@XBRead("/root/agent/id")
String getId();
@XBRead("/root/agent/name")
String getName();
@XBRead("/root/agent/forename")
String getForname();
@XBRead("/root/agent/unit/name")
String getUnitName();
@XBRead("/root/agent/unit/legacyStructurBlablabla/type")
String getUnitType();
}
You will define interfaces instead of classes, but the instances of these interfaces are useable just like POJOs. (with toString(), equals(), hashCode,...). Creating instances of these interfaces is like this:
Agent agent = new XBProjector().io().stream(stream).read(Agent.class);
Upvotes: 1