org.xml.sax.SAXParseException: cvc-elt.1: не удается найти объявление элемента 'tns: root_element' - PullRequest
4 голосов
/ 21 августа 2011

Я потратил последние 2 часа на это. Я не могу понять, почему происходит эта ошибка. У меня есть простой код XSD и XML

XML-файл:

<?xml version="1.0" encoding="UTF-8"?>

<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="root_element" type="string"/>   
</schema>

xsd файл:

<?xml version="1.0" encoding="UTF-8"?>
<root_element>"asd"</root_element>

Мой код Java:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
SchemaFactory s_factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
dbf.setSchema(s_factory.newSchema(new File(schemafile)));  
dbf.setValidating(true);
dbf.setFeature("http://apache.org/xml/features/validation/schema", true);
DocumentBuilder db = dbf.newDocumentBuilder();
CommodityPropsErrorHandler cp_eh = new CommodityPropsErrorHandler();
db.setErrorHandler(cp_eh);
Document doc = db.parse(new File(props_file));

Любые комментарии будут полезны. С уважением

Ответы [ 2 ]

3 голосов
/ 21 августа 2011

Я думаю, что главная проблема с:

dbf.setValidating(true);

Согласно Java API, DocumentBuilderFactory.setValidating:

Указывает, что анализатор, созданный этим кодом, будет проверять документы как они разбираются. По умолчанию это значение установлено на ложь.

Обратите внимание, что здесь «валидация» означает валидирующий парсер, как определено в рекомендации XML. Другими словами, это по сути просто управляет проверкой DTD . (кроме наследства двух свойств определено в JAXP 1.2.)

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

Также вам не нужно:

dbf.setFeature("http://apache.org/xml/features/validation/schema", true);

Ваш рабочий код, вероятно, просто (однако я не знаю, что находится в CommodityPropsErrorHandler классе):

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
SchemaFactory s_factory =
    SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
dbf.setSchema(s_factory.newSchema(new File(schemafile)));  
DocumentBuilder db = dbf.newDocumentBuilder();
CommodityPropsErrorHandler cp_eh = new CommodityPropsErrorHandler();
db.setErrorHandler(cp_eh);
Document doc = db.parse(new File(props_file));

Вот второй, альтернативный подход с предыдущим dbf.setValidating(true); (то есть с использованием этих двух свойств из JAXP, упомянутых в Java API):

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.setValidating(true);

dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
    XMLConstants.W3C_XML_SCHEMA_NS_URI);
dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource",
    new File(schemafile));

DocumentBuilder db = dbf.newDocumentBuilder();
CommodityPropsErrorHandler cp_eh = new CommodityPropsErrorHandler();
db.setErrorHandler(cp_eh);
Document doc = db.parse(new File(props_file));
2 голосов
/ 06 сентября 2013

Эта строка предназначена для информирования пространства имен проверки.В противном случае это даст элемент, которого нет в документе.

dbf.setNamespaceAware(true);
...