/* * Created on 02.12.2003 * * (c) Stabsstelle IKT-Strategie des Bundes */ package at.gv.egovernment.moa.spss.slinterface; import java.util.HashMap; import java.util.StringTokenizer; import org.apache.xml.utils.PrefixResolverDefault; import org.apache.xpath.XPath; import org.apache.xpath.XPathContext; import org.apache.xpath.objects.XObject; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) */ public class XPathUtils { /** * The XPath context for the XPath engine. */ protected XPathContext xPathContext_; /** * The prefix resolver for the XPath engine. */ protected PrefixResolver prefixResolver_; /** * The XPath engine. */ protected XPath xPath_; /* ==================================================================================================== */ public void setupContext(String xPathExpr, Node namespaceNode, String additionalNSPrefixes) throws Exception { try { // Set up a new evaluation context xPathContext_ = new XPathContext(); // Set up the namespace prefix resolver for the XPath engine prefixResolver_ = new PrefixResolver(namespaceNode, additionalNSPrefixes); // Initialize XPath engine xPath_ = new XPath(xPathExpr, null, prefixResolver_, XPath.SELECT, null); } catch (Exception e) { throw new Exception("Setting up XPath evaluation context failed.", e); } } /* ---------------------------------------------------------------------------------------------------- */ public NodeList selectNodeSet(Node contextNode) throws Exception { XObject xObject; try { xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_); return xObject.nodelist(); } catch (Exception e) { throw new Exception("Executing XPath expression failed.", e); } } /* ---------------------------------------------------------------------------------------------------- */ public boolean selectBoolean(Node contextNode) throws Exception { XObject xObject; try { xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_); return xObject.bool(); } catch (Exception e) { throw new Exception("Executing XPath expression failed.", e); } } /* ==================================================================================================== */ /** * Special extension of the {@link org.apache.xml.utils.PrefixResolverDefault} interface. Used to * configure the Apache Xalan XPath engine which is employed as the backbone of this class. */ protected class PrefixResolver extends PrefixResolverDefault { /** * Contains the additionally specified namespace prefix (key) to namespace URI (value) attributions. */ protected HashMap additionalNSPrefixesMap_; /* ================================================================================================== */ /** * Basic constructor. * * @param xpathExpressionContext The namespace declarations in scope for this node will be used to get * the namespace uri for a prefix specified in the XPath expression. * * @param additionalNSPrefixes Allows the specification of additional prefix to uri attributions apart * from the declarations in scope for the parameter * xpathExpressionContext. May be null. */ public PrefixResolver(Node xpathExpressionContext, String additionalNSPrefixes) throws Exception { super(xpathExpressionContext); additionalNSPrefixesMap_ = new HashMap(); // Register the specified additional namespace prefix to namespace uri attributions if (additionalNSPrefixes != null) { StringTokenizer tokenizer = new StringTokenizer(additionalNSPrefixes, " "); while (tokenizer.hasMoreTokens()) { String prefix = tokenizer.nextToken(); if (!tokenizer.hasMoreTokens()) { // There must be an even number of tokens in the string throw new Exception("Parameter \"additionalNSPrefixes\" must have an even number of tokens."); } String uri = tokenizer.nextToken(); additionalNSPrefixesMap_.put(prefix, uri); } } } /* -------------------------------------------------------------------------------------------------- */ /** * Gets the namespace uri for the specified namespace prefix. The additionally specified prefixes * overrule the prefixes found in the specified namespace node. * * @param prefix The namespace prefix for which a namespace uri should be found. * * @return the namespace uri for the specified namespace prefix. */ public String getNamespaceForPrefix(String prefix) { String additionalURI = (String) additionalNSPrefixesMap_.get(prefix); return (additionalURI != null) ? additionalURI : super.getNamespaceForPrefix(prefix); } } }