You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by le...@apache.org on 2003/05/20 12:43:01 UTC

cvs commit: avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath PrefixResolver.java XPathProcessorImpl.java XPathProcessor.java JaxenProcessorImpl.java

leosutic    2003/05/20 03:43:01

  Modified:    xmlutil/src/java/org/apache/excalibur/xml/xpath
                        XPathProcessorImpl.java XPathProcessor.java
                        JaxenProcessorImpl.java
  Added:       xmlutil/src/test/org/apache/excalibur/xml/xpath/test
                        XPathTestCase.xtest XPathTestCase.java
               xmlutil/src/java/org/apache/excalibur/xml/xpath
                        PrefixResolver.java
  Log:
  Applying patch from Bruno Dumon.
  
      http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=105334333727953&w=2:
  
      Attached is a patch that extends the XPathProcessor component so that a
      custom namespace prefix resolver can be provided for each evaluation of
      an XPath expression.
  
      I need this functionality to implement proper xpointer support in
      Cocoon, but it's certainly more widely useful.
  
      The patch introduces a new interface "PrefixResolver", adds additional
      methods to the XPathProcessor interface that take such a PrefixResolver
      as argument, and also includes a little testcase.
  
  Revision  Changes    Path
  1.1                  avalon-excalibur/xmlutil/src/test/org/apache/excalibur/xml/xpath/test/XPathTestCase.xtest
  
  Index: XPathTestCase.xtest
  ===================================================================
  <?xml version="1.0"?>
  <testcase>
  	<annotation>XPathProcessor test case</annotation>
  	<roles>
  		<role name="org.apache.excalibur.xml.dom.DOMParser" shorthand="domparser" default-class="org.apache.excalibur.xml.impl.JaxpParser"/>
  		<role name="org.apache.excalibur.xml.xpath.XPathProcessor" shorthand="xpathprocessor" default-class="org.apache.excalibur.xml.xpath.XPathProcessorImpl"/>
  	</roles>
  	<components>
          <xpathprocessor>
              <namespace-mappings>
                  <namespace prefix="test" uri="http://localhost/test"/>
              </namespace-mappings>
          </xpathprocessor>
  	</components>
  </testcase>
  
  
  1.1                  avalon-excalibur/xmlutil/src/test/org/apache/excalibur/xml/xpath/test/XPathTestCase.java
  
  Index: XPathTestCase.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation. 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 following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software
   *    itself, if and wherever such third-party acknowledgments
   *    normally appear.
   *
   * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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 Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.excalibur.xml.xpath.test;
  
  import org.apache.avalon.excalibur.testcase.ExcaliburTestCase;
  import org.apache.avalon.framework.component.Component;
  import org.apache.excalibur.xml.dom.DOMParser;
  import org.apache.excalibur.xml.xpath.XPathProcessor;
  import org.apache.excalibur.xml.xpath.PrefixResolver;
  import org.xml.sax.InputSource;
  import org.w3c.dom.Document;
  
  import java.io.StringReader;
  
  public class XPathTestCase extends ExcaliburTestCase
  {
      /** A small test document. */
      private static final String CONTENT1 =
          "<?xml version=\"1.0\"?>" +
          "<test:root xmlns:test=\"http://localhost/test\">" +
              "<test:element1/>" +
              "<test:element2/>" +
          "</test:root>";
  
      /** Second testdocument, has a different namespace than {@link #CONTENT1}. */
      private static final String CONTENT2 =
          "<?xml version=\"1.0\"?>" +
          "<test:root xmlns:test=\"http://localhost/test2\">" +
              "<test:element1/>" +
              "<test:element2/>" +
          "</test:root>";
  
      public XPathTestCase(String name) {
          super(name);
      }
  
      public void testXPath() throws Exception {
          DOMParser parser = null;
          XPathProcessor processor = null;
          try {
              parser = (DOMParser)manager.lookup(DOMParser.ROLE);
              processor = (XPathProcessor)manager.lookup(XPathProcessor.ROLE);
  
              Document document1 = parser.parseDocument(new InputSource(new StringReader(CONTENT1)));
              Document document2 = parser.parseDocument(new InputSource(new StringReader(CONTENT2)));
  
              // test with a namespace prefix configured in the component configuration
              String testExpr = "count(/test:root/*)";
              Number number = processor.evaluateAsNumber(document1, testExpr);
              assertEquals(2, number.intValue());
  
              // test with a custom prefix resolver using a different document in a different namespace,
              // to be sure the custom prefix resolver is used
              number = processor.evaluateAsNumber(document2, testExpr, new PrefixResolver() {
                  public String prefixToNamespace(String prefix)
                  {
                      if (prefix.equals("test"))
                          return "http://localhost/test2";
                      return null;
                  }
              });
              assertEquals(2, number.intValue());
  
          } finally {
              if (parser != null)
                  manager.release((Component)parser);
              if (processor != null)
                  manager.release((Component)processor);
          }
      }
  }
  
  
  
  1.12      +116 -36   avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath/XPathProcessorImpl.java
  
  Index: XPathProcessorImpl.java
  ===================================================================
  RCS file: /home/cvs/avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath/XPathProcessorImpl.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- XPathProcessorImpl.java	16 May 2003 15:18:29 -0000	1.11
  +++ XPathProcessorImpl.java	20 May 2003 10:43:00 -0000	1.12
  @@ -64,7 +64,6 @@
   import org.apache.avalon.framework.configuration.ConfigurationException;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.thread.ThreadSafe;
  -import org.apache.xml.utils.PrefixResolver;
   import org.apache.xpath.XPathAPI;
   import org.apache.xpath.objects.XObject;
   import org.w3c.dom.Node;
  @@ -117,15 +116,7 @@
       public Node selectSingleNode( final Node contextNode,
                                     final String str )
       {
  -        try
  -        {
  -            final XObject result = XPathAPI.eval( contextNode, str, this );
  -            return result.nodeset().nextNode();
  -        }
  -        catch( final TransformerException te )
  -        {
  -            return null;
  -        }
  +        return selectSingleNode(contextNode, str, this);
       }
   
       /**
  @@ -139,15 +130,7 @@
       public NodeList selectNodeList( final Node contextNode,
                                       final String str )
       {
  -        try
  -        {
  -            final XObject result = XPathAPI.eval( contextNode, str, this );
  -            return result.nodelist();
  -        }
  -        catch( final TransformerException te )
  -        {
  -            return new EmptyNodeList();
  -        }
  +        return selectNodeList(contextNode, str, this);
       }
   
       /** Evaluate XPath expression within a context.
  @@ -158,9 +141,44 @@
        */
       public boolean evaluateAsBoolean( Node contextNode, String str )
       {
  +        return evaluateAsBoolean(contextNode, str, this);
  +    }
  +
  +    /** Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @return expression result as number.
  +     */
  +    public Number evaluateAsNumber( Node contextNode, String str )
  +    {
  +        return evaluateAsNumber(contextNode, str, this);
  +    }
  +
  +    /** Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @return expression result as string.
  +     */
  +    public String evaluateAsString( Node contextNode, String str )
  +    {
  +        return evaluateAsString(contextNode, str, this);
  +    }
  +
  +    /**
  +     * Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return expression result as boolean.
  +     */
  +    public boolean evaluateAsBoolean(Node contextNode, String str, PrefixResolver resolver)
  +    {
           try
           {
  -            final XObject result = XPathAPI.eval( contextNode, str, this );
  +            final XObject result = XPathAPI.eval( contextNode, str, new XalanResolver(resolver) );
               return result.bool();
           }
           catch( final TransformerException te )
  @@ -169,17 +187,19 @@
           }
       }
   
  -    /** Evaluate XPath expression within a context.
  +    /**
  +     * Evaluate XPath expression within a context.
        *
        * @param contextNode The context node.
        * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
        * @return expression result as number.
        */
  -    public Number evaluateAsNumber( Node contextNode, String str )
  +    public Number evaluateAsNumber(Node contextNode, String str, PrefixResolver resolver)
       {
           try
           {
  -            final XObject result = XPathAPI.eval( contextNode, str, this );
  +            final XObject result = XPathAPI.eval( contextNode, str, new XalanResolver(resolver) );
               return new Double( result.num() );
           }
           catch( final TransformerException te )
  @@ -188,17 +208,19 @@
           }
       }
   
  -    /** Evaluate XPath expression within a context.
  +    /**
  +     * Evaluate XPath expression within a context.
        *
        * @param contextNode The context node.
        * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
        * @return expression result as string.
        */
  -    public String evaluateAsString( Node contextNode, String str )
  +    public String evaluateAsString(Node contextNode, String str, PrefixResolver resolver)
       {
           try
           {
  -            final XObject result = XPathAPI.eval( contextNode, str, this );
  +            final XObject result = XPathAPI.eval( contextNode, str, new XalanResolver(resolver) );
               return result.str();
           }
           catch( final TransformerException te )
  @@ -207,24 +229,82 @@
           }
       }
   
  -    public String getBaseIdentifier()
  +    /**
  +     * Use an XPath string to select a single node.
  +     *
  +     * @param contextNode The node to start searching from.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return The first node found that matches the XPath, or null.
  +     */
  +    public Node selectSingleNode(Node contextNode, String str, PrefixResolver resolver)
       {
  -        return m_baseURI;
  +        try
  +        {
  +            final XObject result = XPathAPI.eval( contextNode, str, new XalanResolver(resolver) );
  +            return result.nodeset().nextNode();
  +        }
  +        catch( final TransformerException te )
  +        {
  +            return null;
  +        }
       }
   
  -    public String getNamespaceForPrefix( String prefix )
  +    /**
  +     *  Use an XPath string to select a nodelist.
  +     *
  +     * @param contextNode The node to start searching from.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return A List, should never be null.
  +     */
  +    public NodeList selectNodeList(Node contextNode, String str, PrefixResolver resolver)
       {
  -        return (String)m_mappings.get( prefix );
  +        try
  +        {
  +            final XObject result = XPathAPI.eval( contextNode, str, new XalanResolver(resolver) );
  +            return result.nodelist();
  +        }
  +        catch( final TransformerException te )
  +        {
  +            return new EmptyNodeList();
  +        }
       }
   
  -    public String getNamespaceForPrefix( String prefix, Node node )
  +    public String prefixToNamespace(String prefix)
       {
  -        return getNamespaceForPrefix( prefix );
  +        return (String)m_mappings.get( prefix );
       }
   
  -    public boolean handlesNullPrefixes()
  -    {
  -        return false;
  +    /**
  +     * A Xalan-specific wrapper for the PrefixResolver.
  +     */
  +    private final class XalanResolver implements org.apache.xml.utils.PrefixResolver {
  +        private final PrefixResolver resolver;
  +
  +        public XalanResolver(PrefixResolver resolver) {
  +            this.resolver = resolver;
  +        }
  +
  +        public String getNamespaceForPrefix(String prefix)
  +        {
  +            return resolver.prefixToNamespace(prefix);
  +        }
  +
  +        public String getNamespaceForPrefix(String prefix, Node context)
  +        {
  +            return resolver.prefixToNamespace(prefix);
  +        }
  +
  +        public String getBaseIdentifier()
  +        {
  +            return m_baseURI;
  +        }
  +
  +        public boolean handlesNullPrefixes()
  +        {
  +            return false;
  +        }
       }
   }
   
  
  
  
  1.7       +56 -5     avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath/XPathProcessor.java
  
  Index: XPathProcessor.java
  ===================================================================
  RCS file: /home/cvs/avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath/XPathProcessor.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XPathProcessor.java	27 Feb 2003 09:24:47 -0000	1.6
  +++ XPathProcessor.java	20 May 2003 10:43:00 -0000	1.7
  @@ -60,6 +60,10 @@
   /**
    * This is the interface of the XPath processor.
    *
  + * <p>All methods have two variants: one which takes a PrefixResolver as an extra
  + * argument, and one which doesn't. The {@link PrefixResolver} interface allows to provide
  + * your own namespace prefix resolving.
  + *
    * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
    * @version CVS $Revision$ $Date$ $Author$
    */
  @@ -98,9 +102,7 @@
       String evaluateAsString( Node contextNode, String str );
   
       /**
  -     * Use an XPath string to select a single node. XPath namespace
  -     * prefixes are resolved from the context node, which may not
  -     * be what you want (see the next method).
  +     * Use an XPath string to select a single node.
        *
        * @param contextNode The node to start searching from.
        * @param str A valid XPath string.
  @@ -110,11 +112,60 @@
   
       /**
        *  Use an XPath string to select a nodelist.
  -     *  XPath namespace prefixes are resolved from the contextNode.
        *
        *  @param contextNode The node to start searching from.
        *  @param str A valid XPath string.
        *  @return A List, should never be null.
        */
       NodeList selectNodeList( Node contextNode, String str );
  +
  +    /**
  +     * Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return expression result as boolean.
  +     */
  +    boolean evaluateAsBoolean( Node contextNode, String str, PrefixResolver resolver );
  +
  +    /**
  +     * Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return expression result as number.
  +     */
  +    Number evaluateAsNumber( Node contextNode, String str, PrefixResolver resolver );
  +
  +    /**
  +     * Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return expression result as string.
  +     */
  +    String evaluateAsString( Node contextNode, String str, PrefixResolver resolver );
  +
  +    /**
  +     * Use an XPath string to select a single node.
  +     *
  +     * @param contextNode The node to start searching from.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return The first node found that matches the XPath, or null.
  +     */
  +    Node selectSingleNode( Node contextNode, String str, PrefixResolver resolver );
  +
  +    /**
  +     *  Use an XPath string to select a nodelist.
  +     *
  +     * @param contextNode The node to start searching from.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return A List, should never be null.
  +     */
  +    NodeList selectNodeList( Node contextNode, String str, PrefixResolver resolver );
   }
  
  
  
  1.11      +114 -33   avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath/JaxenProcessorImpl.java
  
  Index: JaxenProcessorImpl.java
  ===================================================================
  RCS file: /home/cvs/avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath/JaxenProcessorImpl.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- JaxenProcessorImpl.java	27 Feb 2003 09:24:47 -0000	1.10
  +++ JaxenProcessorImpl.java	20 May 2003 10:43:00 -0000	1.11
  @@ -83,7 +83,7 @@
    * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
    * @version CVS $Revision$ $Date$ $Author$
    */
  -public final class JaxenProcessorImpl extends AbstractLogEnabled implements XPathProcessor, Configurable, Component, ThreadSafe, NamespaceContext
  +public final class JaxenProcessorImpl extends AbstractLogEnabled implements XPathProcessor, Configurable, Component, ThreadSafe, PrefixResolver
   {
       private final HashMap m_mappings = new HashMap();
   
  @@ -111,17 +111,7 @@
       public Node selectSingleNode( final Node contextNode,
                                     final String str )
       {
  -        try
  -        {
  -            final DOMXPath path = new DOMXPath( str );
  -            path.setNamespaceContext( this );
  -            return (Node)path.selectSingleNode( contextNode );
  -        }
  -        catch( final Exception e )
  -        {
  -            // ignore it
  -            return null;
  -        }
  +        return selectSingleNode(contextNode, str, this);
       }
   
       /**
  @@ -135,18 +125,7 @@
       public NodeList selectNodeList( final Node contextNode,
                                       final String str )
       {
  -        try
  -        {
  -            final DOMXPath path = new DOMXPath( str );
  -            path.setNamespaceContext( this );
  -            final List list = path.selectNodes( contextNode );
  -            return new SimpleNodeList( list );
  -        }
  -        catch( final Exception e )
  -        {
  -            // ignore it
  -            return new EmptyNodeList();
  -        }
  +        return selectNodeList(contextNode, str, this);
       }
   
       /** Evaluate XPath expression within a context.
  @@ -157,10 +136,45 @@
        */
       public boolean evaluateAsBoolean( Node contextNode, String str )
       {
  +        return evaluateAsBoolean(contextNode, str, this);
  +    }
  +
  +    /** Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @return expression result as number.
  +     */
  +    public Number evaluateAsNumber( Node contextNode, String str )
  +    {
  +        return evaluateAsNumber(contextNode, str, this);
  +    }
  +
  +    /** Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @return expression result as string.
  +     */
  +    public String evaluateAsString( Node contextNode, String str )
  +    {
  +        return evaluateAsString(contextNode, str, this);
  +    }
  +
  +    /**
  +     * Evaluate XPath expression within a context.
  +     *
  +     * @param contextNode The context node.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return expression result as boolean.
  +     */
  +    public boolean evaluateAsBoolean(Node contextNode, String str, PrefixResolver resolver)
  +    {
           try
           {
               final DOMXPath path = new DOMXPath( str );
  -            path.setNamespaceContext( this );
  +            path.setNamespaceContext( new JaxenResolver(resolver) );
               return path.booleanValueOf( contextNode );
           }
           catch( final Exception e )
  @@ -169,18 +183,20 @@
           }
       }
   
  -    /** Evaluate XPath expression within a context.
  +    /**
  +     * Evaluate XPath expression within a context.
        *
        * @param contextNode The context node.
        * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
        * @return expression result as number.
        */
  -    public Number evaluateAsNumber( Node contextNode, String str )
  +    public Number evaluateAsNumber(Node contextNode, String str, PrefixResolver resolver)
       {
           try
           {
               final DOMXPath path = new DOMXPath( str );
  -            path.setNamespaceContext( this );
  +            path.setNamespaceContext( new JaxenResolver(resolver) );
               return path.numberValueOf( contextNode );
           }
           catch( final Exception e )
  @@ -189,18 +205,20 @@
           }
       }
   
  -    /** Evaluate XPath expression within a context.
  +    /**
  +     * Evaluate XPath expression within a context.
        *
        * @param contextNode The context node.
        * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
        * @return expression result as string.
        */
  -    public String evaluateAsString( Node contextNode, String str )
  +    public String evaluateAsString(Node contextNode, String str, PrefixResolver resolver)
       {
           try
           {
               final DOMXPath path = new DOMXPath( str );
  -            path.setNamespaceContext( this );
  +            path.setNamespaceContext( new JaxenResolver(resolver) );
               return path.stringValueOf( contextNode );
           }
           catch( final Exception e )
  @@ -209,8 +227,71 @@
           }
       }
   
  -    public String translateNamespacePrefixToUri( String prefix )
  +    /**
  +     * Use an XPath string to select a single node.
  +     *
  +     * @param contextNode The node to start searching from.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return The first node found that matches the XPath, or null.
  +     */
  +    public Node selectSingleNode(Node contextNode, String str, PrefixResolver resolver)
  +    {
  +        try
  +        {
  +            final DOMXPath path = new DOMXPath( str );
  +            path.setNamespaceContext( new JaxenResolver(resolver) );
  +            return (Node)path.selectSingleNode( contextNode );
  +        }
  +        catch( final Exception e )
  +        {
  +            // ignore it
  +            return null;
  +        }
  +    }
  +
  +    /**
  +     *  Use an XPath string to select a nodelist.
  +     *
  +     * @param contextNode The node to start searching from.
  +     * @param str A valid XPath string.
  +     * @param resolver a PrefixResolver, used for resolving namespace prefixes
  +     * @return A List, should never be null.
  +     */
  +    public NodeList selectNodeList(Node contextNode, String str, PrefixResolver resolver)
  +    {
  +        try
  +        {
  +            final DOMXPath path = new DOMXPath( str );
  +            path.setNamespaceContext( new JaxenResolver(resolver) );
  +            final List list = path.selectNodes( contextNode );
  +            return new SimpleNodeList( list );
  +        }
  +        catch( final Exception e )
  +        {
  +            // ignore it
  +            return new EmptyNodeList();
  +        }
  +    }
  +
  +    public String prefixToNamespace(String prefix)
       {
           return (String)m_mappings.get( prefix );
  +    }
  +
  +    /**
  +     * A Jaxen-specific wrapper for the PrefixResolver.
  +     */
  +    private static class JaxenResolver implements NamespaceContext {
  +        private final PrefixResolver resolver;
  +
  +        public JaxenResolver(PrefixResolver resolver) {
  +            this.resolver = resolver;
  +        }
  +
  +        public String translateNamespacePrefixToUri(String prefix)
  +        {
  +            return resolver.prefixToNamespace(prefix);
  +        }
       }
   }
  
  
  
  1.1                  avalon-excalibur/xmlutil/src/java/org/apache/excalibur/xml/xpath/PrefixResolver.java
  
  Index: PrefixResolver.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 The Apache Software Foundation. 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 following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software
   *    itself, if and wherever such third-party acknowledgments
   *    normally appear.
   *
   * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * 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 APACHE SOFTWARE FOUNDATION OR
   * ITS 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 Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.excalibur.xml.xpath;
  
  /**
   * Implement this interface in case you want to provide your
   * own prefix resolving when evaluating XPath expressions.
   */
  public interface PrefixResolver
  {
      /**
       * Given a namespace prefix, return the corresponding namespace URI,
       * or null if the namespace prefix is not known.
       */
      public String prefixToNamespace(String prefix);
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org