XMLIdFilter: An XMLFilter for xml:id Processing
The XMLIdFilter class is a SAX XMLFilter that supports xml:id Version 1.0.
This filter is a complete implementation of xml:id within the constraints imposed by SAX and the by the caller.
Classes and Documentation Copyright © 2004, 2011 Norman Walsh.
This program and its associated documentation are free software; you can redistribute it and/or modify it in any way shape or form without limitation. It is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This documentation is for Version 1.0 of the classes, which implements the 9 September 2005 Recommendation of xml:id.
- Java JDK 1.4 or later.
- SAX 2.0 or later. If SAX 2.0.1 or later is available, additional attribute type tests will be performed.
- Xerces 2.0 or later for the
- If the SAX
Attributesdoes not support the
isDeclared()method, the filter cannot distinguish between an undeclared xml:id attribute and an xml:id attribute erroneously declared as CDATA.
- If the SAX
Locatorused does not support the
getXMLVersion()method, the filter assumes that all xml:id values must be valid XML 1.0 NCNames. (If the method is available, it tests for valid XML 1.1 NCNames when XML 1.1 is used.)
- The filter uses a hash to keep track of ID values that have been seen. If the caller selects a limited hash size, then duplicate ID values may not be detected.
Errors are reported by calling the SAX XMLFilterImpl's
error() method with an XMLIdException.
- This code is a lightly edited fork of the xmlidfilter project at Java.net.
- Relies on
XML11Charto test the validity of NCNames.
- The Xerces
getXMLVersion()without claiming to implement the
Locator2interface, so we go looking for that method by reflection.
- If an xml:id attribute is promoted, we have to construct a new set
of attributes for the element. This is accomplished by constructing
an instance of
org.xml.sax.helpers.AttributesImpldirectly. This means that a subclass that extends
startElement()will not see the results of calling
super().startElement()reflected in the atts passed to it. Is there a better way?
- If the
XML11Charclasses aren't available at runtime, the filter calls
warning()once and then proceeds, skipping most of the NCName tests; it performs only a very crude test over the ASCII range.
For detailed usage, consult the API documentation.
The distribution includes a test class,
can be used to try out the filter. Make sure that the classes from
this distribution, SAX, and Xerces are on your class path, then run:
java com.nwalsh.xmlidfilter.apps.XMLIdTest [options] yourfile.xml
That will parse yourfile.xml and report any xml:id errors that occur as well as the resulting types of all attributes.
-V: Disable (-v) or enable (-V) validation. False by default.
-N: Disable (-n) or enable (-N) namespace awareness. True by default.
-W: Disable (-w) or enable (-W) xml:id warnings. True by default.
-cclassname: Use classname as the underlying reader class. If not specified, the
SAXParserFactorymechanism will be used to get a parser.
A set of test cases is included in the distribution.
With Another Processor
You can put these classes to work by using the
com.nwalsh.xmlidfilter.XMLIdReader. For example,
Saxon supports a
-x command line
argument to specify the class that should be used to read source
documents. If you specify
transformation will be xml:id aware.