Проверьте документ XML с помощью релакс-нг и пространств имен

Я читаю XML-документ с DocumentBuilder из Java 8 и пытаюсь проверить его с помощью Jing против схемы Relax NG. Это не работает, если XML-документ содержит объявления пространства имен.

Посмотрите на следующий пример:

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

System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI,
XMLSyntaxSchemaFactory.class.getName());

SchemaFactory rngSchemaFactory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
rngSchemaFactory.setProperty("http://relaxng.org/properties/datatype-library-factory", new org.relaxng.datatype.helpers.DatatypeLibraryLoader());
InputStream is = getClass().getResourceAsStream("/path/to/schema.rng");
InputStreamReader rngReader = new InputStreamReader(is, "UTF-8");
Schema schema = rngSchemaFactory.newSchema(new StreamSource(rngReader));

dbf.setSchema(schema);

DocumentBuilder db = dbf.newDocumentBuilder();
db.setErrorHandler(new ErrorHandler());
Document doc = db.parse(Files.newInputStream(xmlFile, StandardOpenOption.READ));

Этот фрагмент кода анализирует документ XML, создает DOM и проверяет документ XML. Однако ErrorHandler получает следующие три сообщения об ошибках:

Line 2, column 96, attribute "xmlns" not allowed here; expected attribute "id" or "unique-identifier"
Line 3, column 96, attribute "xmlns:dc" not allowed here; expected attribute "id"
Line 3, column 96, attribute "xmlns:opf" not allowed here; expected attribute "id"

Первые три строки документа XML выглядят как

<?xml version="1.0"?>
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="p9783701742455">
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">

Документ XML кажется полностью действительным.

Когда я проверяю тот же документ без построения DOM, эти ошибки не встречаются. Посмотрите на следующий фрагмент кода:

System.setProperty(SchemaFactory.class.getName() + ":" + XMLConstants.RELAXNG_NS_URI, XMLSyntaxSchemaFactory.class.getName());
SchemaFactory rngSchemaFactory = SchemaFactory.newInstance(XMLConstants.RELAXNG_NS_URI);
rngSchemaFactory.setProperty("http://relaxng.org/properties/datatype-library-factory", new org.relaxng.datatype.helpers.DatatypeLibraryLoader());

InputStream is = getClass().getResourceAsStream("/path/to/schema.rng");
InputStreamReader rngReader = new InputStreamReader(is, "UTF-8");
Schema schema = rngSchemaFactory.newSchema(new StreamSource(rngReader));

Validator validator = schema.newValidator();
validator.setErrorHandler(new ErrorHandler());
validator.validate(new StreamSource(xmlFile));

Последнее, что у меня есть, это то, что парсер SAX должен иметь следующую функцию:

http://xml.org/sax/features/namespace-prefixes При значении true эта функция указывает, что атрибуты префикса xmlns и xmlns: будут включены в список атрибутов, передаваемый startElement(). Когда false, эти атрибуты опущены.

Я думаю, что это, кажется, причина моей проблемы. Однако DocumentBuilderFactory не поддерживает эту функцию.

0 ответов

Другие вопросы по тегам