XML11NSDTDValidatorpublic class XML11NSDTDValidator extends XML11DTDValidator The DTD validator. The validator implements a document
filter: receiving document events from the scanner; validating
the content and structure; augmenting the InfoSet, if applicable;
and notifying the parser of the information resulting from the
validation process.
Formerly, this component also handled DTD events and grammar construction.
To facilitate the development of a meaningful DTD grammar caching/preparsing
framework, this functionality has been moved into the XMLDTDLoader
class. Therefore, this class no longer implements the DTDFilter
or DTDContentModelFilter interfaces.
This component requires the following features and properties from the
component manager that uses it:
- http://xml.org/sax/features/namespaces
- http://xml.org/sax/features/validation
- http://apache.org/xml/features/validation/dynamic
- http://apache.org/xml/properties/internal/symbol-table
- http://apache.org/xml/properties/internal/error-reporter
- http://apache.org/xml/properties/internal/grammar-pool
- http://apache.org/xml/properties/internal/datatype-validator-factory
|
Fields Summary |
---|
private QName | fAttributeQNameAttribute QName. |
Methods Summary |
---|
protected void | endNamespaceScope(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.Augmentations augs, boolean isEmpty)Handles end element.
// bind element
String eprefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
element.uri = fNamespaceContext.getURI(eprefix);
if (element.uri != null) {
element.prefix = eprefix;
}
// call handlers
if (fDocumentHandler != null) {
if (!isEmpty) {
fDocumentHandler.endElement(element, augs);
}
}
// pop context
fNamespaceContext.popContext();
| protected final void | startNamespaceScope(com.sun.org.apache.xerces.internal.xni.QName element, com.sun.org.apache.xerces.internal.xni.XMLAttributes attributes, com.sun.org.apache.xerces.internal.xni.Augmentations augs)Bind namespaces
// add new namespace context
fNamespaceContext.pushContext();
if (element.prefix == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementXMLNSPrefix",
new Object[] { element.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// search for new namespace bindings
int length = attributes.getLength();
for (int i = 0; i < length; i++) {
String localpart = attributes.getLocalName(i);
String prefix = attributes.getPrefix(i);
// when it's of form xmlns="..." or xmlns:prefix="...",
// it's a namespace declaration. but prefix:xmlns="..." isn't.
if (prefix == XMLSymbols.PREFIX_XMLNS || prefix == XMLSymbols.EMPTY_STRING
&& localpart == XMLSymbols.PREFIX_XMLNS) {
// get the internalized value of this attribute
String uri = fSymbolTable.addSymbol(attributes.getValue(i));
// 1. "xmlns" can't be bound to any namespace
if (prefix == XMLSymbols.PREFIX_XMLNS && localpart == XMLSymbols.PREFIX_XMLNS) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 2. the namespace for "xmlns" can't be bound to any prefix
if (uri == NamespaceContext.XMLNS_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXMLNS",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// 3. "xml" can't be bound to any other namespace than it's own
if (localpart == XMLSymbols.PREFIX_XML) {
if (uri != NamespaceContext.XML_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
// 4. the namespace for "xml" can't be bound to any other prefix
else {
if (uri == NamespaceContext.XML_URI) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"CantBindXML",
new Object[] { attributes.getQName(i)},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
prefix = localpart != XMLSymbols.PREFIX_XMLNS ? localpart : XMLSymbols.EMPTY_STRING;
// Declare prefix in context. Removing the association between a prefix and a
// namespace name is permitted in XML 1.1, so if the uri value is the empty string,
// the prefix is being unbound. -- mrglavas
fNamespaceContext.declarePrefix(prefix, uri.length() != 0 ? uri : null);
}
}
// bind the element
String prefix = element.prefix != null ? element.prefix : XMLSymbols.EMPTY_STRING;
element.uri = fNamespaceContext.getURI(prefix);
if (element.prefix == null && element.uri != null) {
element.prefix = XMLSymbols.EMPTY_STRING;
}
if (element.prefix != null && element.uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"ElementPrefixUnbound",
new Object[] { element.prefix, element.rawname },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
// bind the attributes
for (int i = 0; i < length; i++) {
attributes.getName(i, fAttributeQName);
String aprefix = fAttributeQName.prefix != null ? fAttributeQName.prefix : XMLSymbols.EMPTY_STRING;
String arawname = fAttributeQName.rawname;
if (arawname == XMLSymbols.PREFIX_XMLNS) {
fAttributeQName.uri = fNamespaceContext.getURI(XMLSymbols.PREFIX_XMLNS);
attributes.setName(i, fAttributeQName);
} else if (aprefix != XMLSymbols.EMPTY_STRING) {
fAttributeQName.uri = fNamespaceContext.getURI(aprefix);
if (fAttributeQName.uri == null) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributePrefixUnbound",
new Object[] { element.rawname, arawname, aprefix },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
attributes.setName(i, fAttributeQName);
}
}
// verify that duplicate attributes don't exist
// Example: <foo xmlns:a='NS' xmlns:b='NS' a:attr='v1' b:attr='v2'/>
int attrCount = attributes.getLength();
for (int i = 0; i < attrCount - 1; i++) {
String auri = attributes.getURI(i);
if (auri == null || auri == NamespaceContext.XMLNS_URI) {
continue;
}
String alocalpart = attributes.getLocalName(i);
for (int j = i + 1; j < attrCount; j++) {
String blocalpart = attributes.getLocalName(j);
String buri = attributes.getURI(j);
if (alocalpart == blocalpart && auri == buri) {
fErrorReporter.reportError(
XMLMessageFormatter.XMLNS_DOMAIN,
"AttributeNSNotUnique",
new Object[] { element.rawname, alocalpart, auri },
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
}
}
|
|