SAX validation

So far we only parsed well formed document instances. Our current parser may operate on valid XML instances:

This document instance is well-formed but not valid: Only one element <item> is allowed due to an ill-defined schema. The parser will not report any error or warning. In order to enable validation we need to configure our parser:

xmlReader.setFeature("http://xml.org/sax/features/validation", true);

The string http://xml.org/sax/features/validation serves as a key. Since this is an ordinary string value a parser may or may not implement it. The SAX standard defines two exception classes for dealing with feature related errors:

SAXNotRecognizedException

The feature is not known to the parser.

SAXNotSupportedException

The feature is known to the parser but the parser does not support it or it does not support a specific value being set as a value.

The xml-commons resolver project offers an implementation being able to process various catalog file formats. Maven based project allow the corresponding library import by adding the following dependency:

<dependency>
<groupId>xml-resolver</groupId>
<artifactId>xml-resolver</artifactId>
<version>1.2</version>
</dependency>

We need a properties file CatalogManager.properties defining XML catalogs to be used and additional parameters:

# Catalogs are relative to this properties file
relative-catalogs=false
# Catalog list

catalogs=\
/.../plugins/com.oxygenxml.editor_.../frameworks/xhtml/dtd/xhtmlcatalog.xml;\
/.../plugins/com.oxygenxml.editor_.../frameworks/xhtml11/dtd/xhtmlcatalog.xml
# PUBLIC in favour of SYSTEM
prefer=public

This configuration uses some catalogs from the OxygenEclipse™ plugin. We may now add a resolver to our SAX application by referencing the above configuration file ❶ and registering the resolver to our SAX parser instance ❷:

xmlReader = saxParser.getXMLReader();

// Set up resolving PUBLIC identifier
final CatalogManager cm = new CatalogManager("CatalogManager.properties" ❶ );
final CatalogResolver resolver = new CatalogResolver(cm);
xmlReader.setEntityResolver(resolver) ❷;