2011-12-03 20 views
5

¿Hay alguna forma (con ejemplos de código Java, si es posible) de convertir, sobre la marcha, una entrada XML al JSON, sin ningún conocimiento de los contenidos reales y la estructura de la fuente XML (archivo, cadena, etc.)?Conversión dinámica de XML a JSON

Digamos, por ejemplo, que uno tiene un gran conjunto de datos XML con una estructura desconocida y múltiples niveles de anidamiento, almacenados en un archivo de texto grande. Leer todo en la memoria no es posible (por falta de espacio) y quieren convertir esto en JSON directamente, es decir, sin tener que escribir ningún código para detectar y manejar las etiquetas StAX (por ejemplo, START_ELEMENT, CHARACTERS, END_ELEMENT).

La solución ideal sería la de obtener un Reader o InputStream del convertidor, de modo que, por ejemplo, se suministra el archivo XML y la Reader o InputStream produce JSON, para alimentar a un FileOutputStream, o incluso directamente a una JSON analizador como Jackson. Si eso no es posible, al menos una forma de leer progresivamente un archivo XML, convertir a JSON y escribir en otro archivo sería un compromiso aceptable.

Herramientas que pueden ser utilizados para la conversión de/a XML/JSON (por ejemplo, StaxON, JSON-lib, Jettison, XStream) no parecen hacer eso pero sólo conversión de una estructura conocida.

EDIT: Conseguir un Reader o InputStream de un OutputStream o un escritor (que también abarcaría la "conversión" Hablé de arriba), se puede hacer de varias maneras, aunque para obtener los mejores resultados y la "infinita "tamaños de entrada multihilo está involucrado. Las soluciones se describen en este article in Ostermiller.org y una implementación similar se puede encontrar en el IO-Tools library.

Respuesta

5

Aquí hay un ejemplo trivial que usa la implementación StAX incorporada de Java en parse XML y Jettison en produce JSON. El XMLEventWriter tiene un método conveniente add(XMLEventWriter) para puentear un lector para un escritor, haciendo de este súper simple:

import org.codehaus.jettison.mapped.MappedXMLOutputFactory; 

import javax.xml.stream.XMLEventReader; 
import javax.xml.stream.XMLEventWriter; 
import javax.xml.stream.XMLInputFactory; 
import java.io.StringReader; 
import java.util.HashMap; 

public class Main { 
    public static void main(String[] args) throws Exception { 
     String xml = 
      "<root><foo>foo string</foo><bar><x>1</x><y>5</y></bar></root>"; 
     XMLEventReader reader = XMLInputFactory.newInstance() 
      .createXMLEventReader(new StringReader(xml)); 
     XMLEventWriter writer = new MappedXMLOutputFactory(new HashMap()) 
      .createXMLEventWriter(System.out); 
     writer.add(reader); 
     writer.close(); 
     reader.close(); 
    } 
} 

He creado un proyecto Maven autónomo demostrando este on Github.

+0

Esto proporciona la "escribir en el archivo" solución (o en la salida estándar). ¡Gracias por la respuesta y el esfuerzo extra! – PNS

+0

¿Cómo ignoras las etiquetas de comentarios con esto? XMLEventWriter arroja excepciones cuando hay etiquetas de comentarios en el xml. – ShaggyInjun

+0

@ShaggyInjun: Esa debería ser su propia pregunta, completar con el código de muestra, no un comentario sobre una respuesta de 1.5 años de antigüedad. –

1

Hay una biblioteca underscore-lodash con métodos estáticos de Xml y toJson.

ejemplo Código:

import com.github.underscore.lodash.$; 
import java.util.Map; 
import org.junit.Test; 
import static org.junit.Assert.assertEquals; 

public class StringTest { 

    @Test 
    public void toJsonFromXml() { 
     final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n" 
      + " <FirstItem>1</FirstItem>\n <SecondItem>2</SecondItem>\n</root>"; 
     assertEquals("{\n" 
      + " \"root\": {\n" 
      + " \"FirstItem\": \"1\",\n" 
      + " \"SecondItem\": \"2\"\n" 
      + " }\n" 
      + "}", 
      $.toJson((Map<String, Object>) $.fromXml(xml))); 
    } 
}