[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: XPath against a Document

Subject: RE: XPath against a Document
From: Brian Dupras <briand@xxxxxxxxxxx>
Date: Tue, 15 Feb 2000 15:11:40 -0700
xalan xpath
> 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@xxxxxxx]
> Sent: Tuesday, February 15, 2000 12:17 PM
> To: xsl-list@xxxxxxxxxxxxxxxx
> 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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.