¿Cuál es la mejor biblioteca para el análisis XML en Java [cerrado]

158

Estoy buscando en la biblioteca de Java para analizar XML (configuración compleja y archivos de datos), busqué en Google un poco pero no pude encontrar otro que no sea dom4j (Parece que están trabajando en V2). He echado un vistazo a la configuración de commons pero no No me gusta, Otros proyectos de apache en XML parecen estar en hibernación. No he evaluado dom4j por mí mismo, pero solo quería saber: ¿Java tiene otras bibliotecas de análisis XML de código abierto (buenas)? ¿Y cómo es tu experiencia con dom4j?

Después de la respuesta de @ Voo, permítame preguntarle otra: ¿Debería usar las clases integradas de Java o cualquier biblioteca de terceros como dom4j .. ¿Cuáles son las ventajas?

Premraj
fuente
¿Puedes definir bien? Rendimiento, calidad de API, ¿algo más?
Yishai
Rendimiento y facilidad de uso (sí, calidad de API)
Premraj
3
No ha publicado ningún motivo específico para no utilizar las implementaciones nativas de Java.
Aerodeslizador lleno de anguilas
vtd-xml será el mejor para el rendimiento / uso de memoria y facilidad de uso.
vtd-xml-author

Respuestas:

213

En realidad, Java admite 4 métodos para analizar XML de forma inmediata:

Analizador / generador de DOM: toda la estructura XML se carga en la memoria y puede utilizar los conocidos métodos DOM para trabajar con ella. DOM también le permite escribir en el documento con transformaciones Xslt. Ejemplo:

public static void parse() throws ParserConfigurationException, IOException, SAXException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    factory.setIgnoringElementContentWhitespace(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    File file = new File("test.xml");
    Document doc = builder.parse(file);
    // Do something with the document here.
}

Analizador SAX: solo para leer un documento XML. El analizador Sax ejecuta el documento y llama a los métodos de devolución de llamada del usuario. Existen métodos para iniciar / finalizar un documento, elemento, etc. Están definidos en org.xml.sax.ContentHandler y hay una clase auxiliar vacía DefaultHandler.

public static void parse() throws ParserConfigurationException, SAXException {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setValidating(true);
    SAXParser saxParser = factory.newSAXParser();
    File file = new File("test.xml");
    saxParser.parse(file, new ElementHandler());    // specify handler
}

StAx Reader / Writer: esto funciona con una interfaz orientada al flujo de datos. El programa solicita el siguiente elemento cuando está listo como un cursor / iterador. También puedes crear documentos con él. Leer documento:

public static void parse() throws XMLStreamException, IOException {
    try (FileInputStream fis = new FileInputStream("test.xml")) {
        XMLInputFactory xmlInFact = XMLInputFactory.newInstance();
        XMLStreamReader reader = xmlInFact.createXMLStreamReader(fis);
        while(reader.hasNext()) {
            reader.next(); // do something here
        }
    }
}

Escribir documento:

public static void parse() throws XMLStreamException, IOException {
    try (FileOutputStream fos = new FileOutputStream("test.xml")){
        XMLOutputFactory xmlOutFact = XMLOutputFactory.newInstance();
        XMLStreamWriter writer = xmlOutFact.createXMLStreamWriter(fos);
        writer.writeStartDocument();
        writer.writeStartElement("test");
        // write stuff
        writer.writeEndElement();
    }
}

JAXB: la implementación más reciente para leer documentos XML: es parte de Java 6 en v2. Esto nos permite serializar objetos java de un documento. Usted lee el documento con una clase que implementa una interfaz para javax.xml.bind.Unmarshaller (obtiene una clase para esto de JAXBContext.newInstance). El contexto debe inicializarse con las clases utilizadas, pero solo tiene que especificar las clases raíz y no tener que preocuparse por las clases referenciadas estáticas. Utiliza anotaciones para especificar qué clases deben ser elementos (@XmlRootElement) y qué campos son elementos (@XmlElement) o atributos (@XmlAttribute, ¡qué sorpresa!)

public static void parse() throws JAXBException, IOException {
    try (FileInputStream adrFile = new FileInputStream("test")) {
        JAXBContext ctx = JAXBContext.newInstance(RootElementClass.class);
        Unmarshaller um = ctx.createUnmarshaller();
        RootElementClass rootElement = (RootElementClass) um.unmarshal(adrFile);
    }
}

Escribir documento:

public static void parse(RootElementClass out) throws IOException, JAXBException {
    try (FileOutputStream adrFile = new FileOutputStream("test.xml")) {
        JAXBContext ctx = JAXBContext.newInstance(RootElementClass.class);
        Marshaller ma = ctx.createMarshaller();
        ma.marshal(out, adrFile);
    }
}

Ejemplos copiados descaradamente de algunas diapositivas de conferencias antiguas ;-)

Editar: Acerca de "¿qué API debo usar?". Bueno, depende: no todas las API tienen las mismas capacidades que ves, pero si tienes control sobre las clases que usas para mapear el documento XML, JAXB es mi solución personal favorita, realmente elegante y simple (aunque no la he usado para documentos realmente grandes, podría ser un poco complejo). SAX también es bastante fácil de usar y manténgase alejado de DOM si no tiene una buena razón para usarlo: API antigua y torpe en mi opinión. No creo que haya bibliotecas modernas de terceros que presenten algo especialmente útil que falte en el STL y las bibliotecas estándar tienen las ventajas habituales de estar extremadamente bien probadas, documentadas y estables.

Voo
fuente
@Natix por eso es para la opción "editar". Debería estar mejor ahora.
Kikiwa
44
El manejo de excepciones de @Kikiwa está lo más eliminado posible del punto de esta publicación. Si algún programador incompetente de copiar y pegar continúa y copia fragmentos sin comprender su propósito, obtienen lo que se merecen. No estoy realmente preocupado o interesado por ellos. Lo que diré es que eliminar los bloques try / catch y mostrar la firma del método para documentar qué excepciones pueden generar las diferentes opciones ahorraría espacio y al mismo tiempo preservaría la información interesante. Entonces, si alguien quiere hacer eso, simplemente debe seguir adelante.
Voo
1
(Al mismo tiempo, rechazaré las ediciones que eliminen el try / catch sin denotar la información adicional de alguna otra manera)
Voo
Creo que JAXB ya no se incluye con el JDK en versiones recientes.
Slaw
11

Java admite dos métodos para el análisis XML de fábrica.

SAXParser

Puede usar este analizador si quiere analizar archivos XML grandes y / o no quiere usar mucha memoria.

http://download.oracle.com/javase/6/docs/api/javax/xml/parsers/SAXParserFactory.html

Ejemplo: http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/

DOMParser

Puede usar este analizador si necesita hacer consultas XPath o si necesita tener disponible el DOM completo.

http://download.oracle.com/javase/6/docs/api/javax/xml/parsers/DocumentBuilderFactory.html

Ejemplo: http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/

RAJH
fuente
5

Si desea una API similar a DOM, es decir, una en la que el analizador XML convierte el documento en un árbol de nodos Element y Attribute, entonces hay al menos cuatro para elegir: DOM, JDOM, DOM4J y XOM. La única razón posible para usar DOM es porque se percibe como un estándar y se suministra en el JDK: en todos los demás aspectos, los demás son todos superiores. Mi preferencia, por su combinación de simplicidad, potencia y rendimiento, es XOM.

Y, por supuesto, hay otros estilos de procesamiento: interfaces de analizador de bajo nivel (SAX y StAX), interfaces de enlace de objetos de datos (JAXB) e idiomas declarativos de alto nivel (XSLT, XQuery, XPath). Lo que sea mejor para usted depende de los requisitos de su proyecto y de su gusto personal.

Michael Kay
fuente
2
DOM es un estándar W3C ( w3.org/DOM ). La implementación de Java de este estándar está cubierta por el estándar JAXP ( jcp.org/en/jsr/detail?id=206 ). JAXP es implementado por diferentes proveedores como: Oracle, Apache, etc.
bdoughan
De hecho, nadie usaría DOM si no fuera que (a) se definió como un estándar y tiene múltiples implementaciones, y (b) está incluido en el JDK por defecto. Desde todas las demás perspectivas, JDOM2 y XOM son mucho más preferibles.
Michael Kay
4

El punto de Nikita es excelente: no confundas maduro con malo. XML no ha cambiado mucho.

JDOM sería otra alternativa a DOM4J.

duffymo
fuente
¿Cuál elegirás y por qué?
Premraj
1
Realmente no importa mucho. Ambos son envoltorios de los analizadores SAX y DOM integrados en el JDK. La jerarquía de documentos W3C es detallada y difícil de usar, por lo que DOM4J y JDOM intentan facilitarlo. Me gusta Elliott Rusty Harold, así que tiendo a buscar a JDOM primero.
duffymo
4

No necesita una biblioteca externa para analizar XML en Java. Java ha venido con implementaciones integradas para SAX y DOM por años.

ChrisJ
fuente
1

VTD-XML es la biblioteca de análisis XML de servicio pesado ... es mejor que otros en casi todos los sentidos ... aquí hay un documento de 2013 que analiza todos los marcos de procesamiento XML disponibles en la plataforma Java ...

http://sdiwc.us/digitlib/journal_paper.php?paper=00000582.pdf

vtd-xml-author
fuente
3
Una advertencia: VTD-XML tiene licencia bajo la GPL, que lo descarta en la gran mayoría de las situaciones de desarrollo profesional o comercial. Los ingenieros deben consultar a su propio abogado para un análisis, pero si le pagan por hacer ingeniería, lo más probable es que su organización no permita (y no pueda) permitir el uso de bibliotecas con licencia bajo la GPL.
Sarah G
Ese enlace está muerto
nulo