Greeting everyone, I have been a long time user of XMlBeans but it is
the first time I needed to use the XPath support. Using an old Saxon
release (8.6.1 as documented because is the version that is API
compatible) everything is working perfectly.

My application is Webstart based so I try to reduce the amount of
external dependencies in order to have a small download size, I am
currently using JXPath for some Beans trees searches, so I decided to
patch XMLBeans to try to use JXPath after it fails to find Saxon. I am
attaching the patch so anyone can use it and to know if the changes are
accepted so I can port it to the trunk release instead of 2.3.0.

In the process of developing this patch I found one problem with the
XPath function "id()". The JXPath implemetation of this functions when
it is traversing a DOM tree is to find the document owner and call
getElementById(). the current DOM implementation of XMLBeans only
recognize ID attributes when they are defined on a DTD and does not use
the XML schema information. Even when my XMLBeans model parses a DOM
tree obtained from a XML Schema validating DOM parser, the ID attributes
information is lost because it recreated an internal tree that discards
the "isId" information added by the DOM parser. I tried to use the
schema type information in the method Cur>>isAttrOfTypeId but still do
not find a way, any helps with this is appreciated

--
Robert Marcano
diff -Naur xmlbeans-2.3.0.original/build.xml xmlbeans-2.3.0/build.xml
--- xmlbeans-2.3.0.original/build.xml	2007-05-22 16:17:42.000000000 -0400
+++ xmlbeans-2.3.0/build.xml	2008-02-28 14:38:06.000000000 -0430
@@ -63,6 +63,7 @@
                 <include name="saxon8.jar"/>
                 <include name="saxon8-dom.jar"/>
                 <include name="xcresolver.zip"/>
+                <include name="commons-jxpath.jar"/>
                 <!-- the entries below are to delete the previous versions of the jsr173 jars -->
                 <include name="jsr173.jar"/>
                 <include name="jsr173_api.jar"/>
@@ -93,6 +94,23 @@
       <property name="saxon_dom_jar" value="build/lib/saxon8-dom.jar"/>
     </target>
 
+    <target name="jxpath.find1" if="env.XMLBEANS_EXTERNALS">
+      <property name="jxpath_jar" value="${env.XMLBEANS_EXTERNALS}/commons-jxpath-1.2.jar"/>
+    </target>
+    <target name="jxpath.find2">
+      <property name="jxpath_jar" value="build/lib/commons-jxpath-1.2.jar"/>
+    </target>
+
+
+    <target name="check.jxpath.jar" depends="jxpath.find1,jxpath.find2">
+      <condition property="jxpath.jar.exists">
+        <or>
+          <available file="build/lib/commons-jxpath-1.2.jar"/>
+          <available file="${env.XMLBEANS_EXTERNALS}/commons-jxpath-1.2.jar"/>
+        </or>
+      </condition>
+    </target>
+
     <target name="check.saxon8.jar" depends="saxon.find1,saxon.find2">
       <condition property="saxon8.jar.exists">
         <or>
@@ -102,6 +120,23 @@
       </condition>
     </target>
 
+    <target name="jxpath.jar" depends="check.jxpath.jar, dirs"
+        unless="jxpath.jar.exists">
+        <get dest="external/lib/commons-jxpath-1.2.zip"
+            src="http://mirrors.isc.org/pub/apache/commons/jxpath/binaries/commons-jxpath-1.2.zip";
+            verbose="true" usetimestamp="true" ignoreerrors="true"/>
+        <unzip src="external/lib/commons-jxpath-1.2.zip" dest="external/lib/">
+            <patternset>
+                <include name="commons-jxpath-1.2/commons-jxpath-1.2.jar"/>
+            </patternset>
+        </unzip>
+
+        <move file="external/lib/commons-jxpath-1.2/commons-jxpath-1.2.jar" todir="external/lib"/>
+	<delete dir="external/lib/commons-jxpath-1.2"/>
+        <copy file="external/lib/commons-jxpath-1.2.jar" tofile="build/lib/commons-jxpath-1.2.jar"/>
+    </target>
+
+
     <target name="saxon8.jar" depends="check.saxon8.jar, dirs"
         unless="saxon8.jar.exists">
 	<!-- other saxon urls
@@ -936,7 +971,7 @@
 
     <!-- xpath target ============================================= -->
 
-    <target name="xpath.classes" depends="dirs, xmlpublic.classes, store.classes, saxon8.jar">
+    <target name="xpath.classes" depends="dirs, xmlpublic.classes, store.classes, saxon8.jar, jxpath.jar">
         <mkdir dir="build/classes/xpath_xquery"/>
         <javac
             destdir="build/classes/xpath_xquery"
@@ -949,6 +984,7 @@
                 <pathelement location="build/classes/store"/>
                 <pathelement location="${saxon_jar}"/>
                 <pathelement location="${saxon_dom_jar}"/>
+                <pathelement location="${jxpath_jar}"/>
             </classpath>
         </javac>
     </target>
diff -Naur xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/JXPathXBeansDelegate.java xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/JXPathXBeansDelegate.java
--- xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/JXPathXBeansDelegate.java	1969-12-31 20:00:00.000000000 -0400
+++ xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/JXPathXBeansDelegate.java	2008-02-28 14:42:03.000000000 -0430
@@ -0,0 +1,96 @@
+/*   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.xmlbeans.impl.store;
+
+import java.lang.reflect.Constructor;
+import java.util.Map;
+
+import org.apache.xmlbeans.impl.common.XPath;
+
+
+/**
+ * Date: Feb 27,2008
+ *
+ * Help class to decouple from commons-jxpath.jar
+ */
+public final class JXPathXBeansDelegate
+{
+    protected static boolean _jxpathAvailable = true; //first time assume JXPath is available
+    private static Constructor _constructor;
+
+    private JXPathXBeansDelegate()
+    {}
+
+    static void init()
+    {
+        Class jxpathXPathImpl = null;
+        try
+        {
+            // from xbean_xpath.jar
+            jxpathXPathImpl = Class
+                .forName("org.apache.xmlbeans.impl.xpath.jxpath.XBeansXPath");
+        }
+        catch (ClassNotFoundException e)
+        {
+            _jxpathAvailable = false;
+        }
+        catch (NoClassDefFoundError e)
+        {
+            _jxpathAvailable = false;
+        }
+
+        if (_jxpathAvailable)
+        {
+            try
+            {
+                _constructor =
+                    jxpathXPathImpl.getConstructor(new Class[]{String.class,
+                                                              String.class,
+                                                              Map.class,
+                                                              String.class});
+            }
+            catch (Exception e)
+            {
+                _jxpathAvailable = false;
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    static SelectPathInterface createInstance(String xpath,
+                                              String contextVar,
+                                              Map namespaceMap)
+    {
+        if (_jxpathAvailable && _constructor == null)
+            init();
+
+        if (_constructor == null)
+            return null;
+
+        try
+        {
+            Object defaultNS = namespaceMap.get(XPath._DEFAULT_ELT_NS);
+            if ( defaultNS != null )
+                namespaceMap.remove( XPath._DEFAULT_ELT_NS );
+            return (SelectPathInterface)
+                    _constructor.newInstance(new Object[] {xpath,contextVar,namespaceMap,(String)defaultNS});
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff -Naur xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/Path.java xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/Path.java
--- xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/Path.java	2007-01-11 15:31:45.000000000 -0400
+++ xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/Path.java	2008-02-28 14:42:03.000000000 -0430
@@ -35,12 +35,14 @@
 {
     public static String _useXqrlForXpath = "use xqrl for xpath";
     public static String _useXbeanForXpath = "use xbean for xpath";
+    public static String _useJxpathForXpath = "use jxpath for xpath";
     public static String _forceXqrl2002ForXpathXQuery = "use xqrl-2002 for xpath";
 
     private static final int USE_XBEAN    = 0x01;
     private static final int USE_XQRL     = 0x02;
     private static final int USE_SAXON    = 0x04;
     private static final int USE_XQRL2002 = 0x08;
+    private static final int USE_JXPATH   = 0x16;
 
     Path(String key)
     {
@@ -85,8 +87,9 @@
         int force =
                 options.hasOption(_useXqrlForXpath) ? USE_XQRL
                 : options.hasOption(_useXbeanForXpath) ? USE_XBEAN
+                : options.hasOption(_useJxpathForXpath) ? USE_JXPATH
                 : options.hasOption(_forceXqrl2002ForXpathXQuery) ? USE_XQRL2002
-                : USE_XBEAN|USE_XQRL|USE_SAXON; //set all bits except XQRL2002
+                : USE_XBEAN|USE_XQRL|USE_JXPATH|USE_SAXON; //set all bits except XQRL2002
 
         return getCompiledPath(pathExpr, force, getCurrentNodeVar(options));
     }
@@ -95,7 +98,8 @@
         String currentVar)
     {
         Path path = null;
-        Map namespaces = (force & USE_SAXON) != 0 ? new HashMap() : null;
+        Map namespaces = ((force & USE_SAXON) != 0)
+                && ((force & USE_JXPATH) != 0) ? new HashMap() : null;
 
         if ((force & USE_XBEAN) != 0)
             path = (Path) _xbeanPathCache.get(pathExpr);
@@ -112,7 +116,9 @@
         if (path == null && (force & USE_XQRL) != 0)
             path = getCompiledPathXqrl(pathExpr, currentVar);
         if (path == null && (force & USE_SAXON) != 0)
-            path = getCompiledPathSaxon(pathExpr, currentVar, namespaces);
+            path = getCompiledPathSaxon(pathExpr, currentVar, new HashMap(namespaces));
+        if (path == null && (force & USE_JXPATH) != 0)
+            path = getCompiledPathJxpath(pathExpr, currentVar, new HashMap(namespaces));
         if (path == null && (force & USE_XQRL2002) != 0)
             path = getCompiledPathXqrl2002(pathExpr, currentVar);
 
@@ -125,6 +131,8 @@
                 errMessage.append(" Trying XQRL...");
             if ((force & USE_SAXON) != 0)
                 errMessage.append(" Trying Saxon...");
+            if ((force & USE_JXPATH) != 0)
+                errMessage.append(" Trying JXPath...");
             if ((force & USE_XQRL2002) != 0)
                 errMessage.append(" Trying XQRL2002...");
 
@@ -168,6 +176,13 @@
         if ( namespaces == null )
             namespaces = new HashMap();
 
+        String pathExprNoNsBoundary = removeNsBoundary(pathExpr, currentVar, namespaces);
+        path = SaxonPathImpl.create(pathExprNoNsBoundary, currentVar, namespaces);
+
+        return path;
+    }
+
+    private static String removeNsBoundary(String pathExpr, String currentVar, Map namespaces) {
         try
         {
             XPath.compileXPath(pathExpr, currentVar, namespaces);
@@ -182,14 +197,21 @@
             0 :
             ((Integer) namespaces.get(XPath._NS_BOUNDARY)).intValue();
         namespaces.remove(XPath._NS_BOUNDARY);
-        path = SaxonPathImpl.create(pathExpr.substring(offset),
-            currentVar,
-            namespaces);
+        return pathExpr.substring(offset);
+    }
+
+    static private synchronized Path getCompiledPathJxpath(String pathExpr, String currentVar, Map namespaces)
+    {
+        Path path = null;
+        if ( namespaces == null )
+            namespaces = new HashMap();
+
+        String pathExprNoNsBoundary = removeNsBoundary(pathExpr, currentVar, namespaces);
+        path = JXPathPathImpl.create(pathExprNoNsBoundary, currentVar, namespaces);
 
         return path;
     }
 
-
     public static synchronized String compilePath(String pathExpr, XmlOptions options)
     {
         return getCompiledPath(pathExpr, options)._pathKey;
@@ -435,144 +457,171 @@
         private Cur _cur;
     }
 
-    private static final class SaxonPathImpl extends Path
-    {
+    //
+    // JXPath store specific implementation of compiled path
+    //
 
-        private SaxonXBeansDelegate.SelectPathInterface _xpathImpl;
+    private static final class JXPathPathImpl extends Path
+    {
 
+        private SelectPathInterface _xpathImpl;
 
         static Path create(String pathExpr, String currentNodeVar, Map namespaceMap)
         {
             assert !currentNodeVar.startsWith("$"); // cezar review with ericvas
 
-            SaxonXBeansDelegate.SelectPathInterface impl =
-                    SaxonXBeansDelegate.createInstance(pathExpr, currentNodeVar, namespaceMap);
+            SelectPathInterface impl = 
+                JXPathXBeansDelegate.createInstance(pathExpr, currentNodeVar, namespaceMap);
             if (impl == null)
                 return null;
 
-            return new SaxonPathImpl(impl, pathExpr);
+            return new JXPathPathImpl(impl, pathExpr);
         }
 
-
-        private SaxonPathImpl(SaxonXBeansDelegate.SelectPathInterface xpathImpl,
-                              String pathExpr)
+        private JXPathPathImpl(SelectPathInterface xpathImpl, String pathExpr)
         {
             super(pathExpr);
             _xpathImpl = xpathImpl;
         }
 
-        protected PathEngine execute(Cur c, XmlOptions options)
+        PathEngine execute(Cur c, XmlOptions options)
         {
-            return new SaxonPathEngine(_xpathImpl, c);
+            return new ExternalPathEngine(_xpathImpl, c);
         }
 
-        private static class SaxonPathEngine
-                extends XPath.ExecutionContext
-                implements PathEngine
-        {
-
-            SaxonPathEngine(SaxonXBeansDelegate.SelectPathInterface xpathImpl,
-                            Cur c)
-            {
-                _saxonXpathImpl = xpathImpl;
-                _version = c._locale.version();
-                _cur = c.weakCur(this);
-            }
+    }
 
-            public boolean next(Cur c)
-            {
-                if (!_firstCall)
-                    return false;
+    private static final class SaxonPathImpl extends Path
+    {
 
-                _firstCall = false;
+        private SelectPathInterface _xpathImpl;
 
-                if (_cur != null && _version != _cur._locale.version())
-                    throw new ConcurrentModificationException("Document changed during select");
+        static Path create(String pathExpr, String currentNodeVar, Map namespaceMap)
+        {
+            assert !currentNodeVar.startsWith("$"); // cezar review with ericvas
 
-                List resultsList;
-                Object context_node;
+            SelectPathInterface impl =
+                    SaxonXBeansDelegate.createInstance(pathExpr, currentNodeVar, namespaceMap);
+            if (impl == null)
+                return null;
 
-                context_node = _cur.getDom();
-                resultsList = _saxonXpathImpl.selectPath(context_node);
+            return new SaxonPathImpl(impl, pathExpr);
+        }
 
-                int i;
-                for (i = 0; i < resultsList.size(); i++) {
-                    //simple type function results
-                    Object node = resultsList.get(i);
-                    Cur pos = null;
-                    if (!(node instanceof Node)) {
-                        String value;
+        private SaxonPathImpl(SelectPathInterface xpathImpl,
+                              String pathExpr)
+        {
+            super(pathExpr);
+            _xpathImpl = xpathImpl;
+        }
 
-                        value = resultsList.get(i).toString();
+        protected PathEngine execute(Cur c, XmlOptions options)
+        {
+            return new ExternalPathEngine(_xpathImpl, c);
+        }
 
-                        //we cannot leave the cursor's locale, as
-                        //everything is done in the selections of this cursor
+    }
 
-                        Locale l = c._locale;
-                        try {
-                            pos = l.load("<xml-fragment/>").tempCur();
-                            pos.setValue(value);     
-                            SchemaType type = getType(node);
-                            Locale.autoTypeDocument(pos, type, null);
-                            //move the cur to the actual text
-                            pos.next();
-                        }
-                        catch (Exception e) {
-                            throw new RuntimeException(e);
-                        }
+    private static class ExternalPathEngine extends
+            XPath.ExecutionContext implements PathEngine
+    {
+    
+        ExternalPathEngine(SelectPathInterface xpathImpl, Cur c)
+        {
+            _xpathImpl = xpathImpl;
+            _version = c._locale.version();
+            _cur = c.weakCur(this);
+        }
+        
+        public boolean next(Cur c)
+        {
+            if (!_firstCall)
+                return false;
+        
+            _firstCall = false;
+        
+            if (_cur != null && _version != _cur._locale.version())
+                throw new ConcurrentModificationException("Document changed during select");
+        
+            Object context_node = _cur.getDom();
+            List resultsList = _xpathImpl.selectPath(context_node);
+        
+            int i;
+            for (i = 0; i < resultsList.size(); i++) {
+                //simple type function results
+                Object node = resultsList.get(i);
+                Cur pos = null;
+                if (!(node instanceof Node)) {
+                    String value;
+        
+                    value = resultsList.get(i).toString();
+        
+                    //we cannot leave the cursor's locale, as
+                    //everything is done in the selections of this cursor
+        
+                    Locale l = c._locale;
+                    try {
+                        pos = l.load("<xml-fragment/>").tempCur();
+                        pos.setValue(value);     
+                        SchemaType type = getType(node);
+                        Locale.autoTypeDocument(pos, type, null);
+                        //move the cur to the actual text
+                        pos.next();
                     }
-                    else {
-                        assert (node instanceof DomImpl.Dom):
-                                "New object created in XPATH!";
-                        pos = ((DomImpl.Dom) node).tempCur();
-
+                    catch (Exception e) {
+                        throw new RuntimeException(e);
                     }
-                    c.addToSelection(pos);
-                    pos.release();
                 }
-                release();
-                _saxonXpathImpl = null;
-                return true;
-            }
-
-            private SchemaType getType(Object node)
-            {
-                SchemaType type;
-                if (node instanceof Integer)
-                    type = XmlInteger.type;
-                else if (node instanceof Double)
-                    type = XmlDouble.type;
-                else if (node instanceof Long)
-                    type = XmlLong.type;
-                else if (node instanceof Float)
-                    type = XmlFloat.type;
-                else if (node instanceof BigDecimal)
-                    type = XmlDecimal.type;
-                else if (node instanceof Boolean)
-                    type = XmlBoolean.type;
-                else if (node instanceof String)
-                    type = XmlString.type;
-                else if (node instanceof Date)
-                    type = XmlDate.type;
-                else
-                    type = XmlAnySimpleType.type;
-                return type;
-            }
-
-            public void release()
-            {
-                if (_cur != null) {
-                    _cur.release();
-                    _cur = null;
+                else {
+                    assert (node instanceof DomImpl.Dom):
+                            "New object created in XPATH!";
+                    pos = ((DomImpl.Dom) node).tempCur();
+        
                 }
+                c.addToSelection(pos);
+                pos.release();
             }
-
-            private Cur _cur;
-            private SaxonXBeansDelegate.SelectPathInterface _saxonXpathImpl;
-            private boolean _firstCall = true;
-            private long _version;
+            release();
+            _xpathImpl = null;
+            return true;
+        }
+        
+        private SchemaType getType(Object node)
+        {
+            SchemaType type;
+            if (node instanceof Integer)
+                type = XmlInteger.type;
+            else if (node instanceof Double)
+                type = XmlDouble.type;
+            else if (node instanceof Long)
+                type = XmlLong.type;
+            else if (node instanceof Float)
+                type = XmlFloat.type;
+            else if (node instanceof BigDecimal)
+                type = XmlDecimal.type;
+            else if (node instanceof Boolean)
+                type = XmlBoolean.type;
+            else if (node instanceof String)
+                type = XmlString.type;
+            else if (node instanceof Date)
+                type = XmlDate.type;
+            else
+                type = XmlAnySimpleType.type;
+            return type;
         }
-
+        
+        public void release()
+        {
+            if (_cur != null) {
+                _cur.release();
+                _cur = null;
+            }
+        }
+    
+        private SelectPathInterface _xpathImpl;
+        private Cur _cur;
+        private boolean _firstCall = true;
+        private long _version;
     }
 
 
diff -Naur xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/SaxonXBeansDelegate.java xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/SaxonXBeansDelegate.java
--- xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/SaxonXBeansDelegate.java	2007-01-11 15:31:45.000000000 -0400
+++ xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/SaxonXBeansDelegate.java	2008-02-28 14:42:03.000000000 -0430
@@ -94,7 +94,7 @@
             Object defaultNS = namespaceMap.get(XPath._DEFAULT_ELT_NS);
             if ( defaultNS != null )
                 namespaceMap.remove( XPath._DEFAULT_ELT_NS );
-            return (SaxonXBeansDelegate.SelectPathInterface)
+            return (SelectPathInterface)
                     _constructor.newInstance(new Object[] {xpath,contextVar,namespaceMap,(String)defaultNS});
         }
         catch (Exception e)
@@ -122,12 +122,7 @@
         }
     }
 
-    public static interface SelectPathInterface
-    {
-        public List selectPath(Object node);
-    }
-
-     public static interface QueryInterface
+    public static interface QueryInterface
     {
         public List execQuery(Object node, Map variableBindings);
     }
diff -Naur xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/SelectPathInterface.java xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/SelectPathInterface.java
--- xmlbeans-2.3.0.original/src/store/org/apache/xmlbeans/impl/store/SelectPathInterface.java	1969-12-31 20:00:00.000000000 -0400
+++ xmlbeans-2.3.0/src/store/org/apache/xmlbeans/impl/store/SelectPathInterface.java	2008-02-28 14:42:03.000000000 -0430
@@ -0,0 +1,23 @@
+/*   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.xmlbeans.impl.store;
+
+import java.util.List;
+
+public interface SelectPathInterface
+{
+    public List selectPath(Object node);
+}
\ No newline at end of file
diff -Naur xmlbeans-2.3.0.original/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/jxpath/XBeansXPath.java xmlbeans-2.3.0/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/jxpath/XBeansXPath.java
--- xmlbeans-2.3.0.original/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/jxpath/XBeansXPath.java	1969-12-31 20:00:00.000000000 -0400
+++ xmlbeans-2.3.0/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/jxpath/XBeansXPath.java	2008-02-28 14:42:03.000000000 -0430
@@ -0,0 +1,109 @@
+/*   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package org.apache.xmlbeans.impl.xpath.jxpath;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.jxpath.ri.model.beans.NullPointer;
+import org.apache.commons.jxpath.ri.model.dom.DOMNodePointer;
+import org.apache.xmlbeans.impl.store.SelectPathInterface;
+
+public class XBeansXPath
+        implements SelectPathInterface {
+
+    /**
+     * Construct given an XPath expression string.
+     * @param xpathExpr The XPath expression.
+     * @param contextVar The name of the context variable
+     * @param namespaceMap a map of prefix/uri bindings for NS support
+     * @param defaultNS the uri for the default element NS, if any
+     */
+    public XBeansXPath(String xpathExpr, String contextVar,
+                       Map namespaceMap, String defaultNS)
+    {
+        _queryExpr = xpathExpr;
+        // TODO JXPath does not supports setting the default namespave
+        this.namespaceMap = namespaceMap.entrySet().toArray();
+    }
+
+    /**
+     * Select all nodes that are selectable by this XPath
+     * expression. If multiple nodes match, multiple nodes
+     * will be returned.
+     * <p/>
+     * <p/>
+     * <b>NOTE:</b> In most cases, nodes will be returned
+     * in document-order, as defined by the XML Canonicalization
+     * specification.  The exception occurs when using XPath
+     * expressions involving the <code>union</code> operator
+     * (denoted with the pipe '|' character).
+     * </p>
+     * <p/>
+     * <p/>
+     * <b>NOTE:</b> Param node must be a Dom node which will be used during the xpath
+     * execution and iteration through the results. A call of node.dispose() must be done
+     * after reading all results.
+     * </p>
+     *
+     * @param node The node, nodeset or Context object for evaluation.
+     * This value can be null.
+     * @return The <code>a list</code> of all items selected
+     *         by this XPath expression.
+     */
+    public List selectNodes(Object node)
+    {
+        JXPathContext context = JXPathContext.newContext(node);
+
+        // registering namespace prefixes
+        for (int i = 0; i < namespaceMap.length; i++)
+        {
+            Map.Entry entry = (Map.Entry) namespaceMap[i];
+            context.registerNamespace((String) entry.getKey(),
+                    (String) entry.getValue());
+        }
+        
+        List searchResults = context.selectNodes(_queryExpr);
+        Iterator searchResultsIter = searchResults.iterator();
+        List resultsList = new ArrayList(searchResults.size());
+        // id XPath function is returning internal pointers instead of nodes, so
+        // we need to filter them
+        while (searchResultsIter.hasNext())
+        {
+            Object value = searchResultsIter.next();
+            if (value instanceof DOMNodePointer)
+                value = ((DOMNodePointer)value).getNode();
+            else if (value instanceof NullPointer)
+                value = null;
+                
+            if (value != null)
+                resultsList.add(value);
+        }
+        return resultsList;
+    }
+
+    public List selectPath(Object node)
+    {
+        return selectNodes(node);
+    }
+
+
+    private Object[] namespaceMap;
+    private String _queryExpr;
+}
diff -Naur xmlbeans-2.3.0.original/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/saxon/XBeansXPath.java xmlbeans-2.3.0/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/saxon/XBeansXPath.java
--- xmlbeans-2.3.0.original/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/saxon/XBeansXPath.java	2007-01-11 15:31:55.000000000 -0400
+++ xmlbeans-2.3.0/src/xpath_xquery/org/apache/xmlbeans/impl/xpath/saxon/XBeansXPath.java	2008-02-28 14:42:03.000000000 -0430
@@ -15,7 +15,7 @@
 
 package org.apache.xmlbeans.impl.xpath.saxon;
 
-import org.apache.xmlbeans.impl.store.SaxonXBeansDelegate;
+import org.apache.xmlbeans.impl.store.SelectPathInterface;
 import org.w3c.dom.Node;
 
 import java.util.List;
@@ -35,7 +35,7 @@
 
 
 public class XBeansXPath
-        implements SaxonXBeansDelegate.SelectPathInterface {
+        implements SelectPathInterface {
 
     /**
      * Construct given an XPath expression string.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to