This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
RE: XPath against a Document
- To: "'xsl-list at mulberrytech dot com'" <xsl-list at mulberrytech dot com>
- Subject: RE: XPath against a Document
- From: Brian Dupras <briand at centera dot com>
- Date: Tue, 15 Feb 2000 15:11:40 -0700
- Reply-To: xsl-list at mulberrytech dot com
> Using Xerces and Xalan;
> given a Document (i.e. DocumentImpl) and given a String containing
> an XPath expression, I would like to apply the expression against the
> document to obtain the NodeList that matchs the expression. Is this
> possible ?
here's are two functions I use with xalan 0.19.2 and xerces 1.0.1. These
functions were adapted from the Xalan examples and input from Scott Boag at
Lotus, so I can't claim bragging rights. :)
//exmaple:
// selects all direct <datanode foo='bar'> child elements of any <data>
element in the document
Document doc = <some xml document>;
Node node = selectSingleNode(doc.getDocumentElement(),
"//data/datanode[@foo='bar']");
public static NodeList selectNodes(Node contextNode, String strXPath) throws
SAXException{
// Since we don't have a XML Parser involved here, install some
default support
// for things like namespaces, etc.
// (Changed from: XPathSupportDefault xpathSupport = new
XPathSupportDefault();
// because XPathSupportDefault is weak in a number of areas...
perhaps
// XPathSupportDefault should be done away with.)
XPathSupport xpathSupport = new XMLParserLiaisonDefault();
// Create an object to resolve namespace prefixes. - not needed if
not using namespaces
// Specify that XPath namespaces will be resolved from the
// input context node's document element if it is a root node, or
else
// the current context node (for lack of a better resolution
// space, given the simplicity of this sample code).
PrefixResolver prefixResolver = new com.medwired.pp.MyPrefixResolver
((contextNode.getNodeType() == Node.DOCUMENT_NODE) ?
((Document)contextNode).getDocumentElement() : contextNode);
// Create the XPath object.
XPath xpath = new XPath(xpathSupport, null);
// Create a XPath parser.
XPathProcessorImpl parser = new XPathProcessorImpl(xpathSupport);
parser.initXPath(xpath, strXPath, prefixResolver);
// Execute the XPath, and have it return the result
XObject list = xpath.execute(xpathSupport, contextNode,
prefixResolver);
// Have the XObject return it's result as a NodeSet.
NodeList nl = list.nodeset();
return nl;
}
public static Node selectSingleNode(Node contextNode, String strXPath)
throws SAXException{
NodeList nl = selectNodes(contextNode, strXPath);
return (nl.getLength() > 0) ? nl.item(0) : null;
}
////////////////////////////////////////////
//prefix resolver object referenced above
////////////////////////////////////////////
package com.medwired.pp;
import org.w3c.dom.*;
import org.xml.sax.*;
import org.apache.xerces.dom.*;
import org.apache.xerces.parsers.*;
import org.apache.xalan.xslt.*;
import org.apache.xalan.xpath.*;
import org.apache.xalan.xpath.xml.*;
public class MyPrefixResolver implements PrefixResolver
{
/**
* The URI for the XML namespace.
* (Duplicate of that found in
org.apache.xalan.xpath.xml.XMLParserLiaisonDefault).
*/
public static final String S_XMLNAMESPACEURI =
"http://www.w3.org/XML/1998/namespace";
/**
* The context to resolve the prefix from, if the context
* is not given.
*/
Node m_context;
/**
* Construct a PrefixResolverDefault object.
* @param xpathExpressionContext The context from
* which XPath expression prefixes will be resolved.
* Warning: This will not work correctly if xpathExpressionContext
* is an attribute node.
* @param xpathExpressionContext Node from which to start searching for a
* xmlns attribute that binds a prefix to a namespace (when the namespace
* context is not specified in the getNamespaceForPrefix call).
*/
public MedwiredPrefixResolver(Node xpathExpressionContext){
m_context = xpathExpressionContext;
}
/**
* Given a namespace, get the corrisponding prefix. This assumes that
* the PrevixResolver hold's it's own namespace context, or is a namespace
* context itself.
* @param prefix Prefix to resolve.
* @return Namespace that prefix resolves to, or null if prefix
* is not bound.
*/
public String getNamespaceForPrefix(String prefix){
return getNamespaceForPrefix(prefix, m_context);
}
/**
* Given a namespace, get the corrisponding prefix.
* Warning: This will not work correctly if namespaceContext
* is an attribute node.
* @param prefix Prefix to resolve.
* @param namespaceContext Node from which to start searching for a
* xmlns attribute that binds a prefix to a namespace.
* @return Namespace that prefix resolves to, or null if prefix
* is not bound.
*/
public String getNamespaceForPrefix(String prefix, org.w3c.dom.Node
namespaceContext) {
Node parent = namespaceContext;
String namespace = null;
if(prefix.equals("xml")){
namespace = S_XMLNAMESPACEURI;
} else {
int type;
while ((null != parent) && (null == namespace) && (((type =
parent.getNodeType()) == Node.ELEMENT_NODE) || (type ==
Node.ENTITY_REFERENCE_NODE))){
if (type == Node.ELEMENT_NODE){
NamedNodeMap nnm = parent.getAttributes();
for (int i = 0; i < nnm.getLength(); i ++){
Node attr = nnm.item(i);
String aname = attr.getNodeName();
boolean isPrefix = aname.startsWith("xmlns:");
if (isPrefix || aname.equals("xmlns")){
int index = aname.indexOf(':');
String p = isPrefix ? aname.substring(index+1) : "";
if (p.equals(prefix)){
namespace = attr.getNodeValue();
break;
} //if
} //if
} //for each attrib in context Node
} //if Node.ELEMENT_NODE
parent = parent.getParentNode();
} //while
} //else (not "xml:")
return namespace;
} //getNamespaceForPrefix(String, Node)
} //class MedwiredPrefixResolver
> -----Original Message-----
> From: Paul Levin [mailto:plevin@bii.com]
> Sent: Tuesday, February 15, 2000 12:17 PM
> To: xsl-list@mulberrytech.com
> Subject: XPath against a Document
>
>
> Using Xerces and Xalan;
> given a Document (i.e. DocumentImpl) and given a String containing
> an XPath expression, I would like to apply the expression against the
> document to obtain the NodeList that matchs the expression. Is this
> possible ?
>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list