Validate an xml document with relax ng and namespaces

577 Views Asked by At

I am reading an XML document with DocumentBuilder of java 8 and try to validate it with jing against a Relax NG Schema. This does not work, if the XML document contains namespace declarations.

Look at the following example:

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

This piece of code parses the XML document, builds the DOM and validates the XML document. However, the ErrorHandler receives the following three error messages:

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"

The first three lines of the xml document look like

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

The XML document seems completely valid.

When I validate the same document without building the DOM, these errors are not encountered. Look at the following piece of code:

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

The last piece of information I have, is that a SAX parser should have the following feature:

http://xml.org/sax/features/namespace-prefixes When true, this feature indicates that xmlns and xmlns:prefix attributes will be included in the attributes list passed to startElement( ). When false, these attributes are omitted.

I guess, that this seems to be the cause of my problem. However, the DocumentBuilderFactory does not support this feature.

0

There are 0 best solutions below