Rzeczywiście będziesz potrzebował niestandardowego konwertera, ponieważ jest to kolekcja zagnieżdżona, której nie chcesz pokazywać, a te obiekty mogą mieć inne elementy potomne, które zostałyby zserializowane.
Jest to przypadek nieobsługiwany bezpośrednio przez XStream, ale łatwy do naprawienia za pomocą niestandardowego konwertera.
Możesz znaleźć to wszystko w git clone of your project, który zawiera wszystkie te modyfikacje. Ale ponieważ wszystko powinno być widoczne tutaj, następnie wyjaśniam kluczowe fragmenty tego pytania, w tym przykłady kodu.
Zaimplementowałem taki konwerter dla twojego projektu. Kod robi konwersję to:
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
TestRow test = (TestRow)source;
for (TestArguments arg : test.getArguments()) {
for (ArgObject val : arg.getAllTestArguments()) {
writer.startNode(val.getKey());
writer.addAttribute("type", val.getType());
writer.setValue(val.getVal());
writer.endNode();
}
}
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
TestArguments testargs = new TestArguments();
while (reader.hasMoreChildren()) {
reader.moveDown();
String typeval = reader.getAttribute("type");
if (typeval.isEmpty()) {
typeval = "null";
}
testargs.getAllTestArguments().add(new ArgObject(reader.getNodeName(), typeval, reader.getValue()));
reader.moveUp();
}
TestRow result = new TestRow(testargs);
return result;
}
Będzie serializacji wszystkie ArgObjects do xml z płaskiej struktury węzła zdefiniowanej w ArgConverter
. Deserializacja tworzy obiekt z powrotem z tych danych.
Miałeś dwa błędy w kodzie źródłowym, które uniemożliwiły deserializacji:
- XStream deserializacji nie rozpoznaje wszystkie adnotacje aliasu. Wystąpiły problemy z twoim elementem głównym
SuiteData
(aliasing do pakietu). W tym celu dodałem aliadę do obiektu XStream, takiego jak ten xStream.alias("suite", SuiteData.class);
w twoim XMLDataHelper
.
- Jeśli utworzysz instancję
TestArguments
z domyślnym konstruktorem (ponieważ będziesz musiał przeprowadzić deserializację), wywołasz reset, który przypisuje twojemu członkowi argsWrapper
wartość zerową, co powoduje, że dodanie argumentów jest zupełnie niemożliwe. Naprawiłem, że nowo zainicjowałem zmienną składową w metodzie reset (argsWrapper = new ArrayList<ArgObject>();
).
O ile rozumiem twój kod działa zgodnie z oczekiwaniami dla serializacji/deserializacji. Napisałem mały program testowy, aby wymusić ten proces pod każdym względem i wydaje się, że daje taki sam wynik:
public class XMLDataHelperTest {
public static void main(String[] args) {
File file = new File(System.getProperty("user.dir"), "test.xml");
if (file.isFile()) {
assertTrue(file.delete());
}
// write it once
XMLDataHelper helper = new XMLDataHelper(file.getAbsolutePath());
// read it once
helper = new XMLDataHelper(file.getAbsolutePath());
System.out.println(file);
}
}
Tak, wygląda na to, że zadziałało. Zaktualizowałem moje repozytorium. Po prostu muszę naprawić drobny błąd w moim unmarshalingu, w ustawionych metodach klasy TestArguments. Dzięki. – djangofan
Wspaniale, że działa również dla Ciebie. – Matthias