Это не очень сложно сделать с пользовательским конвертером. Это немного длинный пример, но я надеюсь, что он достаточно прост, чтобы понять суть того, что вам нужно сделать:
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public final class ConverterTest {
public static void main(String[] args) {
XStream xstream = new XStream();
xstream.autodetectAnnotations(true);
xstream.registerConverter(new PositionConverter());
final Position position = new Position();
position.setTitle("The Title");
position.setStartDate("The Start Date");
position.setEndDate("The End Date");
final String xml = xstream.toXML(position);
System.out.println("Generated XML:");
System.out.println(xml);
final Position genPosition = (Position) xstream.fromXML(xml);
System.out.println("Generated Position:");
System.out.println("\tTitle: " + genPosition.getTitle());
System.out.println("\tStart Date: " + genPosition.getStartDate());
System.out.println("\tEnd Date: " + genPosition.getEndDate());
}
@XStreamAlias("Position")
private static class Position {
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
private String title;
private String startDate;
private String endDate;
}
private static class PositionConverter implements Converter {
public boolean canConvert(Class clazz) {
return Position.class == clazz;
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
Position position = (Position)value;
writer.startNode("PositionBorder");
writer.startNode("Title");
writer.setValue(position.getTitle());
writer.endNode();
writer.startNode("StartDate");
writer.setValue(position.getStartDate());
writer.endNode();
writer.startNode("EndDate");
writer.setValue(position.getEndDate());
writer.endNode();
writer.endNode();
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
Position position = new Position();
// move it to <PositionBorder> tag.
reader.moveDown();
// now move it to <Title> tag.
reader.moveDown();
String title = reader.getValue();
position.setTitle(title);
reader.moveUp(); // moves back to <PositionBorder>
reader.moveDown(); // should move down to <StartDate> tag
String startDate = reader.getValue();
position.setStartDate(startDate);
reader.moveUp(); // move back to <PositionBorder>
reader.moveDown(); // should move down to <EndDate> tag
String endDate = reader.getValue();
position.setEndDate(endDate);
reader.moveUp(); // move back to <PositionBorder>
return position;
}
}
}
Попробуйте запустить это и посмотреть, что произойдет. Конечно, вам нужно будет изменить его в соответствии с вашими собственными типами - я просто использовал строки для всех полей Position (и я уверен, что вы и класс Position не вложены), но конвертируете из String Дата (или что-то еще) должно быть довольно тривиальным.
Одна вещь, за которой вы захотите следить (а я, возможно, не понял полностью прямо в моем примере), - это сопоставление ваших вызовов reader.moveDown () и reader.moveUp (). (И, если вы собираетесь выполнить маршалинг вместо простого демаршаллинга - что я не ожидаю от вашего вопроса - вы также захотите сопоставить ваши вызовы writer.startNode () и writer.endNode () Возможно, это не вызовет проблем с этим примером, но я уверен, что это вызовет проблемы, если вы делаете что-то большее или обрабатываете несколько файлов с одним и тем же экземпляром XStream или Converter. Кроме того, если вы попробуете reader.moveDown () из недопустимого местоположения, вы получите действительно ужасное исключение - это должно быть довольно очевидно.
Мне пришлось немного поэкспериментировать с методами moveUp / moveDown, чтобы получить их в нужных местах, поэтому я уверен, что вам нужно будет протестировать и настроить его, пока не получите то, что вам нужно.