2009-08-11 14 views
6

Actualmente estoy deserializando JSON con XStream, y ha funcionado muy bien. Sin embargo, cuando tengo cadena JSON como el siguienteXStream parse JSON sin nodo raíz

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

sobre todo no tiene un nodo raíz, no estoy seguro de cómo analizar la misma. Básicamente, quiero lo opuesto a DROP_ROOT_NODE para la deserialización.

+0

Parece que ha habido una conversación al respecto, y tiene sentido. está basado en un analizador XML, y XML debe contener un nodo raíz. Parece que la respuesta es "no puede". http://www.nabble.com/Serializing-JSON-with-no-root--td21732630.html –

Respuesta

4

La respuesta corta es "no se puede".

XStream necesita saber qué clase instanciar, obtiene ese conocimiento de los datos JSON (o XML). El nombre de clase puede ser alias, pero no puede ser omitido. Puede solucionar por:

  1. envolver manual de su cadena JSON con el nodo raíz que contiene el nombre de la clase (o alias)
  2. Escribir su propio lector de que lo haga por usted. Sin embargo, en este caso, igual tendrá que pasar su nombre de clase (alias) a ese lector, ya sea explícitamente o por convención (por ejemplo, siempre anteponer 'raíz' pero luego configurarlo como alias para su clase en la instancia de XStream) - entonces yo no No creo que esto sea más limpio que el # 1.
+0

¿Puede darnos un ejemplo de cómo hacer la opción 2? – portfoliobuilder

2

usar el siguiente código:

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

¿Qué tal leer JSON sin un nodo raíz? ¿Hay código de muestra que puede proporcionar eso? – raffian

3

Sé que esto es una vieja pregunta, pero voy a publicar mi solución después de un googlear toda la mañana. La respuesta es proporcionar nodo raíz ficticio (etiquetas de inicio y terminación). Con el fin de lograr esto, uno de sus mejores amigos es SequenceInputStream:

Mi código es el siguiente:

 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); 

Aquí he mezclado tres objetos InputStream, siendo las primera y la tercera los que proporcionan la necesaria etiquetas faltantes en el archivo procesado.

Esta solución se inspiró en este SO Question. Espero que esto ayude a alguien.