2013-12-15 21 views
7

W projekcie testów jednostkowych potrzebuję pomocy w ustaleniu, w jaki sposób mogę ukryć 2 niepotrzebne węzły nadrzędne w uformowanym formacie XML? Czy ktoś może mi pomóc dowiedzieć się, jak to zrobić?XStream: jak mogę ukryć 2 niepotrzebne węzły nadrzędne w formacie XML z marshallami?

My marshalled output wygląda następująco:

<suite> 
    <suiteName>Suite 1</suiteName> 
    <sauceURL>http://username-string:[email protected]:80/wd/hub</sauceURL> 
    <tests> 
    <test> 
     <rowArgs> 
     <arg> 
      <enabled type="java.lang.Boolean">true</enabled> 
     </arg> 
     <arg> 
      <testname type="java.lang.String">Test 1</testname> 
     </arg> 
     <arg> 
      <environment type="java.lang.String">portal1</environment> 
     </arg> 
     <arg> 
      <testlocale type="java.lang.String">Grid</testlocale> 
     </arg> 
     <arg> 
      <browser type="java.lang.String">Firefox</browser> 
     </arg> 
     <arg> 
      <url type="java.lang.String">http://google.com</url> 
     </arg> 
     </rowArgs> 
    </test> 
      ... 

Ale chcę ukryć zbędne „rowArgs” i „arg” tag tak, że pozostałe węzły są bezpośrednio w węźle testowym. Jak mogę to zrobić?

Możesz mi pomóc w uzyskaniu see my code HERE, if it helps. Podejrzewam, że muszę napisać własny transformator? Tymczasem będę pracował nad tym eksperymentem.

Odpowiedz

4

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); 
    } 
} 
+0

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

+0

Wspaniale, że działa również dla Ciebie. – Matthias