Pergunta

Em Java, eu posso validar um documento XML contra um esquema XSD usando javax.xml.validation.Validator, ou contra um DTD por simplesmente analisar o documento usando org.xml.sax.XMLReader.

O que eu preciso, porém, é uma maneira de determinar programaticamente se o próprio documento valida contra um DTD (ou seja, ele contém uma declaração <!DOCTYPE ...>) ou um XSD. Idealmente, eu preciso fazer isso sem carregar todo o documento XML na memória. Alguém pode ajudar por favor?

(Alternativamente, se há um única forma de validar um documento XML em Java que funciona para ambos os XSDs e DTDs - e permite costume resolver de recursos - que seria ainda melhor)

Muito obrigado,

A

Foi útil?

Solução

Não há 100% infalível processo para determinar a forma de validar um documento XML arbitrário.

Por exemplo, esta versão 2.4 implantação de aplicativos web descritor especifica um W3 esquema para validar o 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">

No entanto, esta é uma forma igualmente válida de expressar a mesma coisa:

<?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 não parece ter um mecanismo que oferece qualquer dicas em o documento que você deve usá-lo. mecanismos de validação são determinados pelos consumidores documento, e não produtores. Se não me engano, este foi um dos ímpetos de condução da mudança do DTD para mecanismos de validação mais modernos.

Na minha opinião, a sua melhor aposta é a de adaptar o detector mecanismo para o conjunto de tipos de documentos que você está processando, lendo informações de cabeçalho e interpretando-a como apropriado. A StAX analisador é bom para isso - porque é um mecanismo de tração, você pode apenas ler o início do arquivo e em seguida, saia a análise sobre o primeiro elemento

.

Link para mais do mesmo e amostra de código e outros enfeites.

Outras dicas

Veja a descrição do pacote para javax.xml.validation. Ele contém informações sobre e exemplos de validação de ambos os XSDs e DTDs

Você poderia simplesmente usar comparações de string?

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

talvez você possa postar um exemplo de código de como você validar um xml contra um dado DTD. Parece ser fácil para um esquema, mas eu estou lutando para encontrar a forma de fazê-lo com um DTD.

Muito obrigado,

Denis.

Ok eu achei:

    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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top