Как определить, соответствует ли документ XML требованиям DTD или XSD? - PullRequest
2 голосов
/ 30 января 2009

В Java я могу проверить документ XML по схеме XSD, используя javax.xml.validation.Validator, или по DTD, просто проанализировав документ с помощью org.xml.sax.XMLReader.

Однако мне нужен способ программного определения, проверяет ли сам документ соответствие DTD (т. Е. Содержит оператор <!DOCTYPE ...>) или XSD. В идеале мне нужно сделать это без загрузки всего XML-документа в память. Может кто-нибудь, пожалуйста, помогите?

(В качестве альтернативы, если существует единственный способ проверки XML-документа в Java, который работает как для XSD, так и для DTD - и допускает настраиваемое разрешение ресурсов - это было бы еще лучше!)

Большое спасибо,

A

Ответы [ 4 ]

1 голос
/ 21 февраля 2009

Не существует 100% надежного процесса определения способа проверки произвольного XML-документа.

Например, в этой версии 2.4 дескриптор развертывания веб-приложения указывает схему W3 для проверки документа:

<?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">

Однако это одинаково верный способ выразить то же самое:

<?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 , похоже, не имеет механизма, который предлагает любые подсказки в документе, что вы должны его использовать. Механизмы проверки определяются потребителями документов, а не производителями. Если я не ошибаюсь, это был один из стимулов, которые привели к переходу от DTD к более современным механизмам валидации.

По моему мнению, вам лучше всего приспособить детектор механизма к набору типов документов, которые вы обрабатываете, считывая информацию заголовка и интерпретируя ее соответствующим образом. Парсер StAX хорош для этого - поскольку это механизм извлечения, вы можете просто прочитать начало файла и затем прекратить анализ первого элемента.

Ссылка на еще один и тот же и пример кода и еще много чего.

1 голос
/ 30 января 2009

См. Описание пакета для javax.xml.validation . Он содержит информацию и примеры для проверки как XSD, так и DTD

0 голосов
/ 10 февраля 2009

не могли бы вы опубликовать пример кода того, как вы проверяете xml по отношению к данному dtd. Схема кажется простой, но я пытаюсь найти способ сделать это с помощью dtd.

Большое спасибо,

Денис.

Хорошо, я нашел это:

    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.");
    }
0 голосов
/ 31 января 2009

Не могли бы вы просто использовать сравнение строк?

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