2009-08-11 4 views
6

Obecnie deserializuję JSON przy użyciu XStream i działa świetnie. Jednak kiedy mam ciąg JSON jak poniżejXStream parsować JSON bez węzła głównego

{ 
    key1: { an_object: { something: 'foobar' } }, 
    key2: { another_object: { data: 'hi' } 
} 

zwłaszcza że nie ma węzła głównego, nie jestem pewien, jak je analizować. Zasadniczo chcę odwrotności DROP_ROOT_NODE dla deserialization.

+0

Wygląda na to, że rozmowa o tym trwa i ma to sens. jest oparty na parserze XML, a XML musi zawierać węzeł główny. Wygląda na to, że odpowiedź brzmi "nie może". http://www.nabble.com/Serializing-JSON-with-no-root--td21732630.html –

Odpowiedz

4

Krótka odpowiedź brzmi "nie możesz".

XStream musi wiedzieć, jaką klasę utworzyć, pobiera tę wiedzę z danych JSON (lub XML). Nazwa klasy może być aliasowana, ale nie można jej pominąć. Można obejść przez:

  1. Ręcznie owijając swój ciąg JSON z węzła głównego zawierającego nazwę klasy (lub alias)
  2. pisanie własnego czytnika, który zrobi to za Ciebie. Jednak w tym przypadku nadal będziesz musiał przekazać swoją nazwę klasy (alias) do tego czytnika jawnie lub przez konwencję (np. Zawsze przedrostek 'root', a następnie skonfiguruj go jako alias do klasy w instancji XStream) - więc ja wykładam Uważam, że jest to czystsze niż pierwsze.
+0

Czy możesz podać przykład jak wykonać opcję 2? – portfoliobuilder

2

Użyj kodu poniżej:

XStream xstream = new XStream(new JsonHierarchicalStreamDriver() { 
    public HierarchicalStreamWriter createWriter(Writer writer) { 
     return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE); 
    } }); 
+0

Co z odczytaniem JSON bez węzła głównego; czy istnieje przykładowy kod, który możesz podać? – raffian

3

wiem, że to jest stare pytanie, ale wyślę moje rozwiązanie po całym rano googling. Odpowiedź polega na zapewnieniu atrapowego węzła głównego (znaczników początkowych i końcowych). W celu osiągnięcia tego, jeden z twoich najlepszych przyjaciół jest SequenceInputStream:

Mój kod jest następujący:

 reader = new XppDriver().createReader(new SequenceInputStream(
     Collections.enumeration(Arrays.asList(
     new InputStream[] { 
       new ByteArrayInputStream("<PlatformAuditEvents>".getBytes()), 
       new FileInputStream(file), 
       new ByteArrayInputStream("</PlatformAuditEvents>".getBytes()) 
      })) 
    )); 
    in = xstream.createObjectInputStream(reader); 

Tutaj mam mieszane trzy obiekty InputStream, jako pierwszy i trzeci z nich te, zapewniające wymaganą brakujące znaczniki w przetwarzanym pliku.

To rozwiązanie zostało zainspirowane tym SO Question. Mam nadzieję, że to pomaga komuś.