Pregunta

En Java, puedo validar un documento XML contra un esquema XSD usando javax.xml.validation.Validator, o contra un DTD simplemente analizando el documento usando org.xml.sax.XMLReader.

Sin embargo, lo que necesito es una forma de determinar mediante programación si el documento mismo se valida contra un DTD (es decir, contiene una declaración <!DOCTYPE ...>) o un XSD. Idealmente, necesito hacer esto sin cargar todo el documento XML en la memoria. ¿Alguien puede ayudarme?

(Alternativamente, si hay una forma única de validar un documento XML en Java que funciona tanto para XSD como para DTD, y permite la resolución personalizada de recursos, ¡eso sería aún mejor!)

Muchas gracias

A

¿Fue útil?

Solución

No existe un proceso 100% infalible para determinar cómo validar un documento XML arbitrario.

Por ejemplo, esta versión 2.4 descriptor de implementación de aplicaciones web especifica un esquema W3 para validar el documento:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

Sin embargo, esta es una forma igualmente válida de expresar lo mismo:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee">

RELAX NG no parece tener un mecanismo que ofrezca any pistas en el documento que debes usar. Los mecanismos de validación están determinados por los consumidores de documentos, no por los productores. Si no me equivoco, este fue uno de los impulsos que impulsó el cambio de DTD a mecanismos de validación más modernos.

En mi opinión, su mejor opción es adaptar el detector de mecanismo al conjunto de tipos de documentos que está procesando, leer la información del encabezado e interpretarla según corresponda. El StAX parser es bueno para esto: debido a que es un mecanismo de extracción, puede leer el inicio del archivo y luego dejar de analizar el primer elemento.

Enlace a más de lo mismo y código de muestra y otras cosas.

Otros consejos

Consulte la descripción del paquete para javax.xml.validation . Contiene información y ejemplos para validar XSD y DTD

¿Podría usar comparaciones de cadenas?

public enum Type {
    XSD,
    DTD,
    UNKNOWN
};

public Type findType(File f) throws FileNotFoundException, IOException {
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader(f));
        String line;
        // may want to cut this loop off after a certain number of lines
        while ((line = reader.readLine()) != null) {
            line = line.toLowerCase();
            if (line.contains("<!doctype"))
                return Type.DTD;
            else if (line.contains("xsi:schemaLocation"))
                return Type.XSD;
        }
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ex) {}
        }
    }
    return Type.UNKNOWN;
}

¿podría publicar un ejemplo de código de cómo validar un xml contra un determinado dtd? Parece ser fácil para un esquema, pero estoy luchando por encontrar cómo hacerlo con un dtd.

Muchas gracias

Denis.

Ok, lo encontré:

    XMLReader reader = XMLReaderFactory.createXMLReader();

    // try to activate validation
    try {
          // Turn on validation
          reader.setFeature("http://xml.org/sax/features/validation", true);
          // Ensure namespace processing is on (the default)
          reader.setFeature("http://xml.org/sax/features/namespaces", true);
    } catch (SAXException e) {
        System.err.println("Cannot activate validation.");
    }

    try {
        reader.parse("testFiasRequest.xml");
    } catch (IOException e) {
        System.err.println("I/O exception reading XML document");
    } catch (SAXException e) {
        System.err.println("XML exception reading document.");
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top