FileDocCategorySizeDatePackage
XML11NSDTDValidator.javaAPI DocApache Xerces 3.0.19996Fri Sep 14 20:33:54 BST 2007org.apache.xerces.impl.dtd

XML11NSDTDValidator

public 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
xerces.internal
author
Elena Litani, IBM
author
Michael Glavassevich, IBM
version
$Id: XML11NSDTDValidator.java 572055 2007-09-02 17:55:43Z mrglavas $

Fields Summary
private final org.apache.xerces.xni.QName
fAttributeQName
Attribute QName.
Constructors Summary
Methods Summary
protected voidendNamespaceScope(org.apache.xerces.xni.QName element, org.apache.xerces.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 voidstartNamespaceScope(org.apache.xerces.xni.QName element, org.apache.xerces.xni.XMLAttributes attributes, org.apache.xerces.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);
                }
            }
        }