Информация DTD и связанные ошибки при проверке (схема XSD) - их можно игнорировать? - PullRequest
2 голосов
/ 04 марта 2011

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

Я использую парсер SAX и получаю список ошибок.

Нижемой код

  BookValidationErrorHandler errorHandler = new BookValidationErrorHandler();

        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(true);

        SchemaFactory schemaFactory = 
            SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

        factory.setSchema(schemaFactory.newSchema(
            new Source[] {new StreamSource("test.xsd")}));


        javax.xml.parsers.SAXParser parser = factory.newSAXParser();
        org.xml.sax.XMLReader reader = parser.getXMLReader();

        reader.setErrorHandler(errorHandler);
        reader.parse(new InputSource("bad.xml"));

Первая пара ошибок всегда:

Номер строки: 2: Документ недействителен: грамматика не найдена.Номер строки: 2: корневой элемент документа "credits", должен совпадать с корневым элементом DOCTYPE "null".

Мы не можем пойти и отредактировать эти тысячи файлов XML, которые необходимо проверить.

Что-нибудь, что я мог бы легко добавить к передней части источника, чтобы предотвратить это?Есть ли способ сказать парсеру игнорировать эти ошибки, связанные с DTD?Даже не уверен, что означает грамматика.Я вроде понимаю, что означает второй.

Ответы [ 3 ]

7 голосов
/ 04 марта 2011

Настройка setValidating(true) запрашивает проверку DTD и вызывает ошибку, если DTD не существует. Если вы хотите только проверку схемы, а не проверку DTD, используйте setValidating(false). От Javadoc для setValidating():

Чтобы использовать современные языки схем, такие как W3C XML Schema или RELAX NG вместо DTD, вы можете сконфигурировать ваш анализатор как не проверяющий синтаксический анализатор, оставив метод setValidating(boolean) false, а затем используйте метод setSchema(Schema) для связывания схема парсера.

0 голосов
/ 21 января 2015

Вы по-прежнему можете использовать проверяющий анализатор, и вам не нужно предварительно задавать схему в анализаторе, если вы используете JAXP-совместимый анализатор и настроили его правильно согласно документации Oracle :

SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(true);
SAXParser saxParser = spf.newSAXParser();
// Important step next:  Tell the parser which XML schema-definition language to expect:
saxParser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
// Now when we parse a file without a DTD, we no longer get an error 
// (as long as an XSD schema is defined in the file):
saxParser.parse(source, handler);
0 голосов
/ 20 апреля 2011

на этих помостах у меня была такая же проблема; Я нашел эту тему в поисках решения. Моим решением было использовать EntityResolver. Похоже, установить схему не достаточно ... не для меня, по крайней мере. Это пример EntityResolver:

public class CustomResolver implements EntityResolver {
    @Override
    public InputSource resolveEntity(String publicId, String systemId) 
            throws SAXException, IOException {

        if (systemId.equals("http://namespace1.example.com/ex1")) {
            return new InputSource("xsd_for_namespace1_path"));
        } else if (systemId.equals("http://namespace2.example.com/ex2")) {
            return new InputSource("xsd_for_namespace2_path"));
        } else if (systemId.equals("http://namespace3.example.com/ex3")) {
            return new InputSource("xsd_for_namespace3_path")); 
        }

        return null;
    }
}

Я также отключаю свойство setValidating (). Это моя конфигурация парсера:

SAXParserFactory saxpf = SAXParserFactory.newInstance();
saxpf.setNamespaceAware(true);
saxpf.setSchema(getSchema());
saxpf.setValidating(false);
SAXParser saxParser = saxpf.newSAXParser();
saxParser.getParser().setEntityResolver(new XSDResolver());

Метод getSchema () создает экземпляр Schema, как вы делаете это в своем коде, но с большим количеством источников.

Я надеюсь, что это может помочь, кто нашел ту же ошибку.

...