domdocument.java
来自「kaffe Java 解释器语言,源码,Java的子集系统,开放源代码」· Java 代码 · 共 790 行 · 第 1/2 页
JAVA
790 行
/* * Copyright (C) 1999-2001 David Brownell * * This file is part of GNU JAXP, a library. * * GNU JAXP is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * GNU JAXP is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * As a special exception, if you link this library with other files to * produce an executable, this library does not by itself cause the * resulting executable to be covered by the GNU General Public License. * This exception does not however invalidate any other reasons why the * executable file might be covered by the GNU General Public License. */package gnu.xml.dom;import java.util.Enumeration;import org.w3c.dom.*;import org.w3c.dom.traversal.*;/** * <p> "Document" and "DocumentTraversal" implementation. * * <p> Note that when this checks names for legality, it uses an * approximation of the XML rules, not the real ones. Specifically, * it uses Unicode rules, with sufficient tweaks to pass a majority * of basic XML conformance tests. (The huge XML character tables are * hairy to implement.) * * @author David Brownell */public class DomDocument extends DomNode implements Document, DocumentTraversal{ private final DOMImplementation implementation; private boolean checkingCharacters = true; // package private final static String xmlNamespace = "http://www.w3.org/XML/1998/namespace"; final static String xmlnsURI = "http://www.w3.org/2000/xmlns/"; /** * Constructs a Document node, associating it with an instance * of the DomImpl class. * * <p> Note that this constructor disables character checking. * It is normally used when connecting a DOM to an XML parser, * and duplicating such checks is undesirable. When used for * purposes other than connecting to a parser, you should * re-enable that checking. * * @see #setCheckingCharacters */ public DomDocument () { super (null); implementation = new DomImpl (); } /** * Constructs a Document node, associating it with the specified * implementation. This should only be used in conjunction with * a specialized implementation; it will normally be called by * that implementation. * * @see DomImpl * @see #setCheckingCharacters */ protected DomDocument (DOMImplementation impl) { super (null); implementation = impl; } /** * <b>DOM L1</b> * Returns the constant "#document". */ final public String getNodeName () { return "#document"; } /** * <b>DOM L1</b> * Returns the constant DOCUMENT_NODE. */ final public short getNodeType () { return DOCUMENT_NODE; } /** * <b>DOM L1</b> * Returns the document's root element, or null. */ final public Element getDocumentElement () { for (int i = 0; i < getLength (); i++) { Node n = item (i); if (n.getNodeType () == ELEMENT_NODE) return (Element) n; } return null; } /** * <b>DOM L1</b> * Returns the document's DocumentType, or null. */ final public DocumentType getDoctype () { for (int i = 0; i < getLength (); i++) { Node n = item (i); if (n.getNodeType () == DOCUMENT_TYPE_NODE) return (DocumentType) n; } return null; } /** * <b>DOM L1</b> * Returns the document's DOMImplementation. */ final public DOMImplementation getImplementation () { return implementation; } /** * <b>DOM L1 (relocated in DOM L2)</b> * Returns the element with the specified "ID" attribute, or null. * * <p>Returns null unless {@link Consumer} was used to populate internal * DTD declaration information, using package-private APIs. If that * internal DTD information is available, the document may be searched for * the element with that ID. */ public Element getElementById (String id) { DomDoctype doctype = (DomDoctype) getDoctype (); if (doctype == null || !doctype.hasIds () || id == null || id.length () == 0) return null; // yes, this is linear in size of document. // it'd be easy enough to maintain a hashtable. Node current = getDocumentElement (); Node temp; if (current == null) return null; while (current != this) { // done? if (current.getNodeType () == ELEMENT_NODE) { Element element = (Element) current; DomDoctype.ElementInfo info; info = doctype.getElementInfo (current.getNodeName ()); if (id.equals (element.getAttribute (info.getIdAttr ()))) return element; } // descend? if (current.hasChildNodes ()) { current = current.getFirstChild (); continue; } // lateral? temp = current.getNextSibling (); if (temp != null) { current = temp; continue; } // back up ... do { temp = current.getParentNode (); if (temp == null) return null; current = temp; temp = current.getNextSibling (); } while (temp == null); current = temp; } return null; } private void checkNewChild (Node newChild) { if (newChild.getNodeType () == ELEMENT_NODE && getDocumentElement () != null) throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR, null, newChild, 0); if (newChild.getNodeType () == DOCUMENT_TYPE_NODE && getDoctype () != null) throw new DomEx (DomEx.HIERARCHY_REQUEST_ERR, null, newChild, 0); } /** * <b>DOM L1</b> * Appends the specified node to this node's list of children, * enforcing the constraints that there be only one root element * and one document type child. */ public Node appendChild (Node newChild) { checkNewChild (newChild); return super.appendChild (newChild); } /** * <b>DOM L1</b> * Inserts the specified node in this node's list of children, * enforcing the constraints that there be only one root element * and one document type child. */ public Node insertBefore (Node newChild, Node refChild) { checkNewChild (newChild); return super.insertBefore (newChild, refChild); } /** * <b>DOM L1</b> * Replaces the specified node in this node's list of children, * enforcing the constraints that there be only one root element * and one document type child. */ public Node replaceChild (Node newChild, Node refChild) { if (!(newChild.getNodeType () == ELEMENT_NODE && refChild.getNodeType () != ELEMENT_NODE) && !(newChild.getNodeType () == DOCUMENT_TYPE_NODE && refChild.getNodeType () != ELEMENT_NODE)) checkNewChild (newChild); return super.replaceChild (newChild, refChild); } // NOTE: DOM can't really tell when the name of an entity, // notation, or PI must follow the namespace rules (excluding // colons) instead of the XML rules (which allow them without // much restriction). That's an API issue. verifyXmlName // aims to enforce the XML rules, not the namespace rules. /** * Throws a DOM exception if the specified name is not a legal XML 1.0 * name. Actually this uses a very similar set of rules, closer to * Unicode rules than to the rules encoded in the large table at the * end of the XML 1.0 specification. * * @exception DomException INVALID_CHARACTER_ERR if the name isn't * legal as an XML name. */ static public void verifyXmlName (String name) { char c; int len = name.length (); if (len == 0) throw new DomEx (DomEx.NAMESPACE_ERR, name, null, 0); // NOTE: these aren't really the XML rules, but they're // a close approximation that's simple to implement. c = name.charAt (0); if (!Character.isUnicodeIdentifierStart (c) && c != ':' && c != '_') throw new DomEx (DomEx.INVALID_CHARACTER_ERR, name, null, c); for (int i = 1; i < len; i++) { c = name.charAt (i); if (!Character.isUnicodeIdentifierPart (c) && c != ':'&& c != '_' && c != '.' && c != '-' && !isExtender (c)) throw new DomEx (DomEx.INVALID_CHARACTER_ERR, name, null, c); } } static private boolean isExtender (char c) { // [88] Extender ::= ... return c == 0x00b7 || c == 0x02d0 || c == 0x02d1 || c == 0x0387 || c == 0x0640 || c == 0x0e46 || c == 0x0ec6 || c == 0x3005 || (c >= 0x3031 && c <= 0x3035) || (c >= 0x309d && c <= 0x309e) || (c >= 0x30fc && c <= 0x30fe); } // package private static void verifyNamespaceName (String name) { int index = name.indexOf (':'); if (index < 0) { verifyXmlName (name); return; } if (name.lastIndexOf (':') != index) throw new DomEx (DomEx.NAMESPACE_ERR, name, null, 0); verifyXmlName (name.substring (0, index)); verifyXmlName (name.substring (index + 1)); } // package private static void verifyXmlCharacters (String value) { int len = value.length (); for (int i = 0; i < len; i++) { char c = value.charAt (i); // assume surrogate pairing checks out OK, for simplicity if (c >= 0x0020 && c <= 0xFFFD) continue; if (c == '\n' || c == '\t' || c == '\r') continue; throw new DomEx (DomEx.INVALID_CHARACTER_ERR, value, null, c); } } // package private static void verifyXmlCharacters (char buf [], int off, int len) { for (int i = 0; i < len; i++) { char c = buf [off + i]; // assume surrogate pairing checks out OK, for simplicity if (c >= 0x0020 && c <= 0xFFFD) continue; if (c == '\n' || c == '\t' || c == '\r') continue; throw new DomEx (DomEx.INVALID_CHARACTER_ERR, new String (buf, off, len), null, c); } } /** * Controls whether certain expensive checks, duplicating those that * conformant XML parsers must perform, are made. */ final public void setCheckingCharacters (boolean value) { checkingCharacters = value; } /** * Returns true if certain expensive checks are performed. * Those checks are intended to reject illegal names, and characters * that are illegal as XML characters. */ final public boolean isCheckingCharacters () { return checkingCharacters; } /** * <b>DOM L1</b> * Returns a newly created element with the specified name. */ public Element createElement (String name) { Element element;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?