📄 documentnavigator.java
字号:
/*
* $Header: /cvsroot/ozone/ozone/modules/xml/dom4j/src/org/jaxen/dom/DocumentNavigator.java,v 1.1 2003/11/02 18:33:52 per_nyfelt Exp $
* $Revision: 1.1 $
* $Date: 2003/11/02 18:33:52 $
*
* ====================================================================
*
* Copyright (C) 2000-2002 bob mcwhirter & James Strachan.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions, and the disclaimer that follows
* these conditions in the documentation and/or other materials
* provided with the distribution.
*
* 3. The name "Jaxen" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact license@jaxen.org.
*
* 4. Products derived from this software may not be called "Jaxen", nor
* may "Jaxen" appear in their name, without prior written permission
* from the Jaxen Project Management (pm@jaxen.org).
*
* In addition, we request (but do not require) that you include in the
* end-user documentation provided with the redistribution and/or in the
* software itself an acknowledgement equivalent to the following:
* "This product includes software developed by the
* Jaxen Project (http://www.jaxen.org/)."
* Alternatively, the acknowledgment may be graphical using the logos
* available at http://www.jaxen.org/
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE Jaxen AUTHORS OR THE PROJECT
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* ====================================================================
* This software consists of voluntary contributions made by many
* individuals on behalf of the Jaxen Project and was originally
* created by bob mcwhirter <bob@werken.com> and
* James Strachan <jstrachan@apache.org>. For more information on the
* Jaxen Project, please see <http://www.jaxen.org/>.
*
* $Id: DocumentNavigator.java,v 1.1 2003/11/02 18:33:52 per_nyfelt Exp $
*/
// DocumentNavigator.java - Jaxen adapter for the W3C DOM level 2.
// This file is in the Public Domain, and comes with NO WARRANTY.
package org.jaxen.dom;
import org.jaxen.DefaultNavigator;
import org.jaxen.FunctionCallException;
import org.jaxen.XPath;
import org.saxpath.SAXPathException;
import org.w3c.dom.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.util.HashMap;
import java.util.Iterator;
import java.util.NoSuchElementException;
/** Interface for navigating around the W3C DOM Level 2 object model.
*
* <p>
* This class is not intended for direct usage, but is
* used by the Jaxen engine during evaluation.
* </p>
*
* <p>This class implements the org.jaxen.DefaultNavigator interface
* for the Jaxen XPath library, version 1.0beta3 (it is not guaranteed
* to work with subsequent releases). This adapter allows the Jaxen
* library to be used to execute XPath queries against any object tree
* that implements the DOM level 2 interfaces.</p>
*
* <p>Note: DOM level 2 does not include a node representing an XML
* Namespace declaration. This navigator will return Namespace decls
* as instantiations of the custom {@link NamespaceNode} class, and
* users will have to check result sets to locate and isolate
* these.</p>
*
* @author David Megginson
* @author James Strachan
*
* @see XPath
* @see NamespaceNode
*/
public class DocumentNavigator extends DefaultNavigator {
////////////////////////////////////////////////////////////////////
// Constants.
////////////////////////////////////////////////////////////////////
/**
* Constant: empty iterator.
*/
private final static Iterator EMPTY_ITERATOR =
new HashMap().values().iterator();
/**
* Constant: singleton navigator.
*/
private final static DocumentNavigator SINGLETON =
new DocumentNavigator();
////////////////////////////////////////////////////////////////////
// Constructor.
////////////////////////////////////////////////////////////////////
/**
* Default Constructor.
*/
public DocumentNavigator() {
}
/**
* Get a singleton DocumentNavigator for efficiency.
*
* @return A singleton instance of a DocumentNavigator.
*/
public static DocumentNavigator getInstance() {
return SINGLETON;
}
////////////////////////////////////////////////////////////////////
// Implementation of org.jaxen.DefaultNavigator.
////////////////////////////////////////////////////////////////////
/**
* Get an iterator over all of this node's children.
*
* @param contextNode The context node for the child axis.
* @return A possibly-empty iterator (not null).
*/
public Iterator getChildAxisIterator(Object contextNode) {
return new NodeIterator((Node) contextNode) {
protected Node getFirstNode(Node node) {
return node.getFirstChild();
}
protected Node getNextNode(Node node) {
return node.getNextSibling();
}
};
}
/**
* Get a (single-member) iterator over this node's parent.
*
* @param contextNode the context node for the parent axis.
* @return A possibly-empty iterator (not null).
*/
public Iterator getParentAxisIterator(Object contextNode) {
Node node = (Node) contextNode;
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
return new NodeIterator(node) {
protected Node getFirstNode(Node n) {
// FIXME: assumes castability.
return ((Attr) n).getOwnerElement();
}
protected Node getNextNode(Node n) {
return null;
}
};
} else {
return new NodeIterator(node) {
protected Node getFirstNode(Node n) {
return n.getParentNode();
}
protected Node getNextNode(Node n) {
return null;
}
};
}
}
/**
* Get an iterator over all following siblings.
*
* @param contextNode the context node for the sibling iterator.
* @return A possibly-empty iterator (not null).
*/
public Iterator getFollowingSiblingAxisIterator(Object contextNode) {
return new NodeIterator((Node) contextNode) {
protected Node getFirstNode(Node node) {
return getNextNode(node);
}
protected Node getNextNode(Node node) {
return node.getNextSibling();
}
};
}
/**
* Get an iterator over all preceding siblings.
*
* @param contextNode The context node for the preceding sibling axis.
* @return A possibly-empty iterator (not null).
*/
public Iterator getPrecedingSiblingAxisIterator(Object contextNode) {
return new NodeIterator((Node) contextNode) {
protected Node getFirstNode(Node node) {
return getNextNode(node);
}
protected Node getNextNode(Node node) {
return node.getPreviousSibling();
}
};
}
/**
* Get an iterator over all following nodes, depth-first.
*
* @param contextNode The context node for the following axis.
* @return A possibly-empty iterator (not null).
*/
public Iterator getFollowingAxisIterator(Object contextNode) {
return new NodeIterator((Node) contextNode) {
protected Node getFirstNode(Node node) {
if (node == null)
return null;
else {
Node sibling = node.getNextSibling();
if (sibling == null)
return getFirstNode(node.getParentNode());
else
return sibling;
}
}
protected Node getNextNode(Node node) {
if (node == null)
return null;
else {
Node n = node.getFirstChild();
if (n == null)
n = node.getNextSibling();
if (n == null)
return getFirstNode(node.getParentNode());
else
return n;
}
}
};
}
/**
* Get an iterator over all preceding nodes, depth-first.
*
* @param contextNode The context node for the preceding axis.
* @return A possibly-empty iterator (not null).
*/
public Iterator getPrecedingAxisIterator(Object contextNode) {
return new NodeIterator((Node) contextNode) {
protected Node getFirstNode(Node node) {
if (node == null)
return null;
else {
Node sibling = node.getPreviousSibling();
if (sibling == null)
return getFirstNode(node.getParentNode());
else
return sibling;
}
}
protected Node getNextNode(Node node) {
if (node == null)
return null;
else {
Node n = node.getLastChild();
if (n == null)
n = node.getPreviousSibling();
if (n == null)
return getFirstNode(node.getParentNode());
else
return n;
}
}
};
}
/**
* Get an iterator over all attributes.
*
* @param contextNode The context node for the attribute axis.
* @return A possibly-empty iterator (not null).
*/
public Iterator getAttributeAxisIterator(Object contextNode) {
if (isElement(contextNode)) {
return new AttributeIterator((Node) contextNode);
} else {
return EMPTY_ITERATOR;
}
}
/**
* Get an iterator over all declared Namespaces.
*
* <p>Note: this iterator is not live: it takes a snapshot
* and that snapshot remains static during the life of
* the iterator (i.e. it won't reflect subsequent changes
* to the DOM).</p>
*
* @param contextNode The context node for the Namespace axis.
* @return A possibly-empty iterator (not null).
*/
public Iterator getNamespaceAxisIterator(Object contextNode) {
// Only elements have Namespace nodes
if (isElement(contextNode)) {
HashMap nsMap = new HashMap();
// Start at the current node at walk
// up to the root, noting what Namespace
// declarations are in force.
// TODO: deal with empty URI for
// cancelling Namespace scope
for (Node n = (Node) contextNode;
n != null;
n = n.getParentNode()) {
if (n.hasAttributes()) {
NamedNodeMap atts = n.getAttributes();
int length = atts.getLength();
for (int i = 0; i < length; i++) {
Node att = atts.item(i);
if (att.getNodeName().startsWith("xmlns")) {
NamespaceNode ns =
new NamespaceNode((Node) contextNode, att);
// Add only if there's not a closer
// declaration in force.
String name = ns.getNodeName();
if (!nsMap.containsKey(name))
nsMap.put(name, ns);
}
}
}
}
// Section 5.4 of the XPath rec requires
// this to be present.
nsMap.put("xml",
new
NamespaceNode((Node) contextNode,
"xml",
"http://www.w3.org/XML/1998/namespace"));
// An empty default Namespace cancels
// any previous default.
NamespaceNode defaultNS = (NamespaceNode) nsMap.get("");
if (defaultNS != null && defaultNS.getNodeValue().equals(""))
nsMap.remove("");
return nsMap.values().iterator();
} else {
return EMPTY_ITERATOR;
}
}
/** Returns a parsed form of the given xpath string, which will be suitable
* for queries on DOM documents.
*/
public XPath parseXPath(String xpath) throws SAXPathException {
return new DOMXPath(xpath);
}
/**
* Get the top-level document node.
*
* @param contextNode Any node in the document.
* @return The root node.
*/
public Object getDocumentNode(Object contextNode) {
if (isDocument(contextNode))
return contextNode;
else
return ((Node) contextNode).getOwnerDocument();
}
/**
* Get the Namespace URI of an element.
*
* @param object The target node.
* @return A string (possibly empty) if the node is an element,
* and null otherwise.
*/
public String getElementNamespaceUri(Object object) {
String uri = ((Node) object).getNamespaceURI();
return uri;
}
/**
* Get the local name of an element.
*
* @param object The target node.
* @return A string representing the unqualified local name
* if the node is an element, or null otherwise.
*/
public String getElementName(Object object) {
String name = ((Node) object).getLocalName();
if (name == null)
name = ((Node) object).getNodeName();
return name;
}
/**
* Get the qualified name of an element.
*
* @param object The target node.
* @return A string representing the qualified (i.e. possibly
* prefixed) name if the node is an element, or null otherwise.
*/
public String getElementQName(Object object) {
String qname = ((Node) object).getNodeName();
if (qname == null)
qname = ((Node) object).getLocalName();
return qname;
}
/**
* Get the Namespace URI of an attribute.
*
* @param object The target node.
* @param A possibly-empty string representing the Namespace URI
* if the node is an attribute, or null otherwise.
*/
public String getAttributeNamespaceUri(Object object) {
String uri = ((Node) object).getNamespaceURI();
return uri;
}
/**
* Get the local name of an attribute.
*
* @param object The target node.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -