// You can redistribute this software and/or modify it under the terms of
// the Infozone Software License version 2 published by the Infozone Group
// (http://www.infozone-group.org).
//
// Copyright (C) @year@ by The Infozone Group. All rights reserved.
//
// $Id: XPathQueryImpl.java,v 1.1 2002/05/10 08:59:12 per_nyfelt Exp $
package org.infozone.tools.xml.queries.xalan;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.NodeFilter;
import org.infozone.tools.xml.queries.XObject;
import org.infozone.tools.xml.queries.XPathQuery;
import org.apache.xalan.xpath.*;
import org.apache.xalan.xpath.xml.PrefixResolver;
import org.apache.xalan.xpath.xml.PrefixResolverDefault;
import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
/**
* @version $Revision: 1.1 $ $Date: 2002/05/10 08:59:12 $
* @author <a href="http://www.softwarebuero.de">SMB</a>
*/
public final class XPathQueryImpl implements XPathQuery {
//
// Data
//
private String qstring;
private Node rootNode;
private Node namespace;
private NodeFilter filter;
private boolean hasChanged = true;
private XPathSupport xpathSupport;
private XPathProcessorImpl parser;
private XPath xpath;
private PrefixResolver prefixResolver;
public XPathQueryImpl() {
// Since we don't have a XML Parser involved here, install some
// default support for things like namespaces, etc.
xpathSupport = new XMLParserLiaisonDefault();
// Create a XPath parser.
parser = new org.apache.xalan.xpath.XPathProcessorImpl (xpathSupport);
// Create the XPath object.
xpath = new XPath();
}
public void setQString( String qstring ) throws Exception {
this.qstring = qstring;
this.hasChanged = true;
}
public void setNamespace( Node namespace ) throws Exception {
this.namespace = namespace;
this.hasChanged = true;
}
public void setNodeFilter( NodeFilter filter ) throws Exception {
this.filter = filter;
this.hasChanged = true;
}
protected void prepare() throws Exception {
// Create an object to resolve namespace prefixes.
// XPath namespaces are resolved from the input root node's
// document element if it is a root node, or else the current root node.
prefixResolver = namespace != null ? new PrefixResolverDefault (namespace):
new PrefixResolverDefault (rootNode);
// parse the specified Query-String and build an Parse-Tree
parser.initXPath (xpath, qstring, prefixResolver);
hasChanged = false;
}
/**
* Execute the xpath.
*
* @param rootNode The node from which the query should start or null.
* @param nameSpace The node that resolves namespace queries or null.
* @param filter The node filter which is to apply while querying or null.
* @return The XObject insulating the query result.
*/
public XObject execute( Node rootNode ) throws Exception {
if (rootNode.getNodeType() == Node.DOCUMENT_NODE) {
rootNode = ((Document)rootNode).getDocumentElement ();
}
this.rootNode = rootNode;
prepare();
// execute the XPath query on the specified root node
return new XObjectImpl (xpath.execute (xpathSupport, rootNode, prefixResolver));
}
}