parser2.java

来自「java jdk 1.4的源码」· Java 代码 · 共 1,790 行 · 第 1/5 页

JAVA
1,790
字号
    // CHAPTER 3:  Logical Structures    //    private boolean maybeElement (ElementValidator validator)    throws IOException, SAXException    {        // [39] element ::= EmptyElemTag | Stag content ETag        // [40] STag ::= '<' Name (S Attribute)* S? '>'        NameCacheEntry          name;        ElementDecl             element;        boolean                 haveAttributes = false;        boolean                 hasContent = true;        int                     startLine;        // the leading "<" has already been consumed        name = maybeGetNameCacheEntry ();        // n.b. InputEntity guarantees 1+N char pushback always,        // and maybeGetName won't use more than one to see if        // it's instead "<?", "<!--", "<![CDATA[", or an error.        if (name == null)            return false;        // XXX Test for namespace conformance here        // if (namespaces) {            // some code testing name.name        // }                    // report validity errors ASAP        if (validator != null)            validator.consume (name.name);        element = (ElementDecl) elements.get (name.name);        if (supportValidation && isValidating) {            if (element == null || element.contentType == null) {                error ("V-005", new Object [] { name.name });                // minimize repetitive diagnostics                element = new ElementDecl (name.name);                element.contentType = strANY;                elements.put (name.name, element);            }            if (validator == null                    && rootElementName != null                    && !rootElementName.equals (name.name))                error ("V-006", new Object [] { name.name, rootElementName });        }        // save the line number here so we can give better diagnostics        // by identifying where the element started; WF errors may be        // reported thousands of lines "late".        startLine = in.getLineNumber ();        // Invariant: attTmp and nsAttTmp are empty except briefly in this        // method they are not empty iff haveAttributes is true        // Track whether we saw whitespace before an attribute;        // in some cases it's required, though superfluous        boolean         sawWhite = in.maybeWhitespace ();        // These are exceptions from the first pass; they should be ignored        // if there's a second pass, but reported otherwise.  A second pass        // occurs when a namespace declaration is found in the first pass.	Vector exceptions = null;        // SAX2 Namespace processing        if (namespaces) {            nsSupport.pushContext();            seenNSDecl = false;        }        // Each pass through this loop reads        //      Name eq AttValue S?        // Loop exits on ">", "/>", or error        for (;;) {            if (in.peekc ('>'))                break;            // [44] EmptyElementTag ::= '<' Name (S Attribute)* S? '/>'            if (in.peekc ('/')) {                hasContent = false;                break;            }            //Need to have a whitespace between attributes.            if (!sawWhite)                fatal ("P-030");            // [41] Attribute ::= Name Eq AttValue            String              attQName;            AttributeDecl       info;            String              value;            attQName = maybeGetName ();            // Need to do this as we have already consumed the             // whitespace and didn't see the end tag.            if (attQName == null)                fatal ("P-031", new Object [] { new Character (getc ()) });            if (attTmp.getValue (attQName) != null)                fatal ("P-032", new Object [] { attQName });            // [25] Eq ::= S? '=' S?            in.maybeWhitespace ();            nextChar ('=', "F-026", attQName);            in.maybeWhitespace ();            // We are not in the DTD => PEs are not recognized => we no            // longer need to expand PEs => don't expand PEs in AttValue =>            // doLexicalPE = false and call parseLiteral(isEntityValue =            // false) both            doLexicalPE = false;            parseLiteral (false);            // We are no longer in the DTD so we never need to expand PEs            sawWhite = in.maybeWhitespace ();            // normalize and check values right away.            info = (element == null)                    ? null                    : (AttributeDecl) element.attributes.get (attQName);            if (info == null) {                if (supportValidation && isValidating)                    error ("V-007", new Object [] { attQName, name.name });                value = strTmp.toString ();            } else {                if (!AttributeDecl.CDATA.equals (info.type)) {                    value = normalize (!info.isFromInternalSubset);                    if (supportValidation && isValidating)                        validateAttributeSyntax (info, value);                } else                    value = strTmp.toString ();                if (supportValidation && isValidating                        && info.isFixed                        && !value.equals (info.defaultValue))                    error ("V-008",                        new Object [] {attQName, name.name, info.defaultValue});            }            // assert(value != null)            if (XmlLang.equals (attQName) && !isXmlLang (value))                error ("P-033", new Object [] { value });            String type = (info == null) ? AttributeDecl.CDATA : info.type;            String defaultValue = (info == null) ? null : info.defaultValue;            if (namespaces) {                exceptions = processAttributeNS(attQName, type, value,                                                defaultValue, true, false,                                                exceptions);            } else {                // No namespaces case                attTmp.addAttribute("", "", attQName, type, value,                                    defaultValue, true);            }            haveAttributes = true;        }        if (element != null)            attTmp.setIdAttributeName (element.id);        // if we had ATTLIST decls, handle required & defaulted attributes        // before telling next layer about this element        if (element != null && element.attributes.size () != 0) {            haveAttributes = defaultAttributes(element) || haveAttributes;        }        // Ensure that this element's namespace declarations apply to all of        // this element's attributes as well.  If there was a Namespace        // declaration, we have to make a second pass just to be safe -- this        // will happen very rarely, possibly only once for each document.        if (seenNSDecl) {            // assert(namespaces == true)            int length = attTmp.getLength();            for (int i = 0; i < length; i++) {                String attQName = attTmp.getQName(i);                if (attQName.startsWith("xmlns")) {                    // Could be a namespace declaration                    if (attQName.length() == 5 || attQName.charAt(5) == ':') {                        // Default or non-default NS declaration                        continue;                    }                }                // assert(not a namespace declaration)                String attName[] = processName(attQName, true, false);                attTmp.setURI(i, attName[0]);                attTmp.setLocalName(i, attName[1]);            }	} else if (exceptions != null && errHandler != null) {	    for (int i = 0; i < exceptions.size(); i++) {		errHandler.error((SAXParseException)(exceptions.elementAt(i)));            }        }        // OK, finally report the event.        if (namespaces) {            String[] parts = processName(name.name, false, false);            contentHandler.startElement(parts[0], parts[1], parts[2], attTmp);        } else {            contentHandler.startElement("", "", name.name, attTmp);        }        // Clear temporaries only when necessary because this may be        // expensive and a doc may have lots of elements w/o attributes        if (haveAttributes) {            attTmp.clear();            if (supportValidation && isValidating && namespaces && !prefixes) {                nsAttTmp.removeAllElements();            }        }        // prepare to validate the content of this element.        // in nonvalidating parsers, this accepts ANY content        validator = newValidator (element);                if (hasContent) {            content (element, false, validator);            // [42] ETag ::= '</' Name S? '>'            // ... content swallowed "</"            if (!in.peek (name.name, name.chars))                fatal ("P-034", new Object []                    { name.name, new Integer (startLine) });            in.maybeWhitespace ();        }        nextChar ('>', "F-027", name.name);        validator.done ();        if (namespaces) {            // Split the name.  Unfortunately, we can't always reuse the            // info from the startElement event above b/c this element may            // have subelements and a global temporary is used.            String[] parts = processName(name.name, false, false);            // Report appropriate events...            contentHandler.endElement(parts[0], parts[1], parts[2]);            Enumeration prefixes = nsSupport.getDeclaredPrefixes();            while (prefixes.hasMoreElements()) {                String prefix = (String)prefixes.nextElement();                contentHandler.endPrefixMapping(prefix);            }            nsSupport.popContext();        } else {            contentHandler.endElement("", "", name.name);        }        return true;    }    /**     * Process attributes for namespace support.  This is mostly common     * code that gets called from two places and was factored out.  The     * <code>isDefaulting</code> param specifies where the code is called     * from.     *     * @param isDefaulting true iff we are processing this attribute from     *                     the <code>defaultAttributes(...)</code> method     *     * The namespace processing code is derived from the SAX2 ParserAdapter     * code.  This code should be kept in sync with ParserAdapter bug     * fixes.     *     * Note: Modifies <code>seenNSDecl</code> iff a xmlns attribute, ie a     * namespace decl, was found.  Modifies <code>attTmp</code> and     * <code>nsAttTmp</code>.     */    private Vector processAttributeNS(String attQName, String type,                                      String value, String defaultValue,                                      boolean isSpecified, boolean isDefaulting,                                      Vector exceptions)        throws SAXException    {        // assert(namespaces == true)      nonNamespace:        if (attQName.startsWith("xmlns")) {            // Could be a namespace declaration            boolean defaultNSDecl = attQName.length() == 5;            if (!defaultNSDecl && attQName.charAt(5) != ':') {                // Not a namespace declaration                break nonNamespace;            }            // Must be some kind of namespace declaration            String prefix;            if (defaultNSDecl) {                // Default namespace, so use empty string as prefix                prefix = "";            } else {                // Non-default namespace decl, extract the prefix                prefix = attQName.substring(6);            }            if (!nsSupport.declarePrefix(prefix, value)) {                error("P-083", new Object[] { prefix });            }            contentHandler.startPrefixMapping(prefix, value);            // We may need to add this attribute to appropriate lists            if (prefixes) {                attTmp.addAttribute("", prefix, attQName.intern(),                                    type, value, defaultValue, isSpecified);            } else if (supportValidation && isValidating && !isDefaulting) {                // Add this namespace attribute to a different list that                // will be used to check for #REQUIRED attributes later.                // Since "prefixes" is false, these are not reported to the                // ContentHandler.  This step is not needed during the                // second pass of attribute processing where default values                // are provided.                nsAttTmp.addElement(attQName);            }            seenNSDecl = true;            return exceptions;        }        // This isn't a namespace declaration.        try {            String attName[] = processName(attQName, true, true);            attTmp.addAttribute(attName[0], attName[1], attName[2], type,                                value, defaultValue, isSpecified);        } catch (SAXException e) {            if (exceptions == null) {                exceptions = new Vector();            }            exceptions.addElement(e);            attTmp.addAttribute("", attQName, attQName, type, value,                                defaultValue, isSpecified);        }        return exceptions;    }    /**     * Process a qualified (prefixed) name.     *     * <p>If the name has an undeclared prefix, use only the qname     * and make an ErrorHandler.error callback in case the app is     * interested.</p>     *     * @param qName The qualified (prefixed) name.     * @param isAttribute true if this is an attribute name.     * @return The name split into three parts.     * @exception org.xml.sax.SAXException The client may throw     *            an exception if there is an error callback.     */    private String[] processName(String qName, boolean isAttribute,                                 boolean useException)        throws SAXException    {        // assert(namespaces == true)        String parts[] = nsSupport.processName(qN

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?