From 757d1639876bd3f9ed1a4649f7efb432806c1e51 Mon Sep 17 00:00:00 2001
From: Alberto Massari <amassari@apache.org>
Date: Fri, 2 Feb 2007 17:35:22 +0000
Subject: [PATCH] Implemented the DOML3 XPath interfaces, reusing the XPath
 processor used inside the XMLSchema validation; this means it understands
 only a limited subset of the XPath syntax, and can only return DOMElement
 nodes. However, it could be useful for simple navigations, or maybe be later
 expanded

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@502666 13f79535-47bb-0310-9956-ffa450edef68
---
 .../BCB6/Xerces-all/XercesLib/XercesLib.bpr   |   8 +-
 .../Xerces-all/XercesLib/XercesLib.mak        |   5 +-
 .../VC6/xerces-all/XercesLib/XercesLib.dsp    |  24 ++
 .../xerces-all/XercesLib/XercesLib.vcproj     |  18 ++
 .../VC8/xerces-all/XercesLib/XercesLib.vcproj |  24 ++
 src/Makefile.am                               |   6 +
 src/xercesc/NLS/EN_US/XMLErrList_EN_US.Xml    |   5 +
 src/xercesc/dom/DOMLSException.cpp            |   3 -
 src/xercesc/dom/DOMLSException.hpp            |  43 ----
 src/xercesc/dom/DOMXPathEvaluator.hpp         |  18 +-
 src/xercesc/dom/DOMXPathException.cpp         |  19 +-
 src/xercesc/dom/DOMXPathException.hpp         |  31 +--
 src/xercesc/dom/DOMXPathExpression.hpp        |  27 ++-
 src/xercesc/dom/DOMXPathNamespace.hpp         |   2 +-
 src/xercesc/dom/DOMXPathResult.hpp            |  36 +--
 src/xercesc/dom/impl/DOMDocumentImpl.cpp      |  23 +-
 .../dom/impl/DOMImplementationImpl.cpp        |   6 +
 .../dom/impl/DOMXPathExpressionImpl.cpp       | 207 ++++++++++++++++++
 .../dom/impl/DOMXPathExpressionImpl.hpp       |  59 +++++
 .../dom/impl/DOMXPathNSResolverImpl.cpp       |  47 ++++
 .../dom/impl/DOMXPathNSResolverImpl.hpp       |  43 ++++
 src/xercesc/dom/impl/DOMXPathResultImpl.cpp   | 110 ++++++++++
 src/xercesc/dom/impl/DOMXPathResultImpl.hpp   |  57 +++++
 .../util/MsgLoaders/ICU/resources/en_US.txt   |   3 +
 .../InMemory/XercesMessages_en_US.hpp         |   9 +-
 .../MsgCatalog/XercesMessages_en_US.Msg       |  13 +-
 src/xercesc/util/MsgLoaders/Win32/Version.rc  |  13 +-
 src/xercesc/util/XMLDOMMsg.hpp                |  23 +-
 .../validators/schema/NamespaceScope.hpp      |  18 +-
 .../schema/identity/XPathMatcher.hpp          |   4 +-
 .../schema/identity/XercesXPath.cpp           |   4 +-
 .../schema/identity/XercesXPath.hpp           |   8 +-
 tests/src/DOM/DOMTest/DTest.cpp               | 159 +++++++++++---
 tests/src/DOM/DOMTest/DTest.h                 |   1 +
 tests/src/XSTSHarness/XSTSHarnessHandlers.cpp |  87 +++++---
 35 files changed, 943 insertions(+), 220 deletions(-)
 create mode 100644 src/xercesc/dom/impl/DOMXPathExpressionImpl.cpp
 create mode 100644 src/xercesc/dom/impl/DOMXPathExpressionImpl.hpp
 create mode 100644 src/xercesc/dom/impl/DOMXPathNSResolverImpl.cpp
 create mode 100644 src/xercesc/dom/impl/DOMXPathNSResolverImpl.hpp
 create mode 100644 src/xercesc/dom/impl/DOMXPathResultImpl.cpp
 create mode 100644 src/xercesc/dom/impl/DOMXPathResultImpl.hpp

diff --git a/Projects/Win32/BCB6/Xerces-all/XercesLib/XercesLib.bpr b/Projects/Win32/BCB6/Xerces-all/XercesLib/XercesLib.bpr
index 07bbde35c..8e0acab02 100644
--- a/Projects/Win32/BCB6/Xerces-all/XercesLib/XercesLib.bpr
+++ b/Projects/Win32/BCB6/Xerces-all/XercesLib/XercesLib.bpr
@@ -303,7 +303,10 @@
       ..\..\..\..\..\Build\Win32\BCB6\obj\XSWildcard.obj 
       ..\..\..\..\..\Build\Win32\BCB6\obj\DOMLSException.obj 
       ..\..\..\..\..\Build\Win32\BCB6\obj\DOMLSOutputImpl.obj 
-      ..\..\..\..\..\Build\Win32\BCB6\obj\DOMLSInputImpl.obj"/>
+      ..\..\..\..\..\Build\Win32\BCB6\obj\DOMLSInputImpl.obj
+      ..\..\..\..\..\Build\Win32\BCB6\obj\DOMXPathExpressionImpl.obj
+      ..\..\..\..\..\Build\Win32\BCB6\obj\DOMXPathNSResolverImpl.obj
+      ..\..\..\..\..\Build\Win32\BCB6\obj\DOMXPathResultImpl.obj"/>
     <RESFILES value=""/>
     <IDLFILES value=""/>
     <IDLGENFILES value=""/>
@@ -670,6 +673,9 @@
       <FILE FILENAME="..\..\..\..\..\src\xercesc\dom\DOMLSException.cpp" FORMNAME="" UNITNAME="DOMLSException" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="..\..\..\..\..\src\xercesc\dom\impl\DOMLSOutputImpl.cpp" FORMNAME="" UNITNAME="DOMLSOutputImpl.cpp" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
       <FILE FILENAME="..\..\..\..\..\src\xercesc\dom\impl\DOMLSInputImpl.cpp" FORMNAME="" UNITNAME="DOMLSInputImpl.cpp" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathExpressionImpl.cpp" FORMNAME="" UNITNAME="DOMXPathExpressionImpl.cpp" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathNSResolverImpl.cpp" FORMNAME="" UNITNAME="DOMXPathNSResolverImpl.cpp" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
+      <FILE FILENAME="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathResultImpl.cpp" FORMNAME="" UNITNAME="DOMXPathResultImpl.cpp" CONTAINERID="CCompiler" DESIGNCLASS="" LOCALCOMMAND=""/>
   </FILELIST>
   <BUILDTOOLS>
   </BUILDTOOLS>
diff --git a/Projects/Win32/BCC.551/Xerces-all/XercesLib/XercesLib.mak b/Projects/Win32/BCC.551/Xerces-all/XercesLib/XercesLib.mak
index 138f6a526..fc8dc5dc5 100644
--- a/Projects/Win32/BCC.551/Xerces-all/XercesLib/XercesLib.mak
+++ b/Projects/Win32/BCC.551/Xerces-all/XercesLib/XercesLib.mak
@@ -305,7 +305,10 @@ OBJFILES = $(TARGETPATH)\obj\XercesLib.obj \
     $(TARGETPATH)\obj\XMLInitializer.obj \
     $(TARGETPATH)\obj\WindowsAtomicOpMgr.obj \
     $(TARGETPATH)\obj\WindowsFileMgr.obj \
-    $(TARGETPATH)\obj\WindowsMutexMgr.obj
+    $(TARGETPATH)\obj\WindowsMutexMgr.obj \
+    $(TARGETPATH)\obj\DOMXPathExpressionImpl.obj \
+    $(TARGETPATH)\obj\DOMXPathNSResolverImpl.obj \
+    $(TARGETPATH)\obj\DOMXPathResultImpl.obj
 RESFILES = 
 MAINSOURCE = XercesLib.cpp
 RESDEPEN = $(RESFILES)
diff --git a/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp b/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
index a612eff9f..9511bf615 100644
--- a/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
+++ b/Projects/Win32/VC6/xerces-all/XercesLib/XercesLib.dsp
@@ -3143,6 +3143,30 @@ SOURCE=..\..\..\..\..\src\xercesc\dom\impl\DOMTypeInfoImpl.hpp
 # End Source File
 # Begin Source File
 
+SOURCE=..\..\..\..\..\src\xercesc\dom\impl\DOMXPathExpressionImpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\xercesc\dom\impl\DOMXPathExpressionImpl.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\xercesc\dom\impl\DOMXPathNSResolverImpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\xercesc\dom\impl\DOMXPathNSResolverImpl.hpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\xercesc\dom\impl\DOMXPathResultImpl.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\..\..\src\xercesc\dom\impl\DOMXPathResultImpl.hpp
+# End Source File
+# Begin Source File
+
 SOURCE=..\..\..\..\..\src\xercesc\dom\impl\XSDElementNSImpl.cpp
 # End Source File
 # Begin Source File
diff --git a/Projects/Win32/VC7.1/xerces-all/XercesLib/XercesLib.vcproj b/Projects/Win32/VC7.1/xerces-all/XercesLib/XercesLib.vcproj
index 8ed7a3e1b..feb993e36 100644
--- a/Projects/Win32/VC7.1/xerces-all/XercesLib/XercesLib.vcproj
+++ b/Projects/Win32/VC7.1/xerces-all/XercesLib/XercesLib.vcproj
@@ -2727,6 +2727,24 @@ copy $(InputDir)\$(InputName).msvc.hpp $(InputPath)
 				<File
 					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMTypeInfoImpl.hpp">
 				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathExpressionImpl.cpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathExpressionImpl.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathNSResolverImpl.cpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathNSResolverImpl.hpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathResultImpl.cpp">
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathResultImpl.hpp">
+				</File>
 				<File
 					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\XSDElementNSImpl.cpp">
 				</File>
diff --git a/Projects/Win32/VC8/xerces-all/XercesLib/XercesLib.vcproj b/Projects/Win32/VC8/xerces-all/XercesLib/XercesLib.vcproj
index eb476ceb5..2bacab8eb 100644
--- a/Projects/Win32/VC8/xerces-all/XercesLib/XercesLib.vcproj
+++ b/Projects/Win32/VC8/xerces-all/XercesLib/XercesLib.vcproj
@@ -3636,6 +3636,30 @@
 					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMTypeInfoImpl.hpp"
 					>
 				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathExpressionImpl.cpp"
+                    >
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathExpressionImpl.hpp"
+                    >
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathNSResolverImpl.cpp"
+                    >
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathNSResolverImpl.hpp"
+                    >
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathResultImpl.cpp"
+                    >
+				</File>
+				<File
+					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\DOMXPathResultImpl.hpp"
+                    >
+				</File>
 				<File
 					RelativePath="..\..\..\..\..\src\xercesc\dom\impl\XSDElementNSImpl.cpp"
 					>
diff --git a/src/Makefile.am b/src/Makefile.am
index 5d6d30b1f..e7f963029 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -382,6 +382,9 @@ domimpl_headers	= \
 	xercesc/dom/impl/DOMLSSerializerImpl.hpp \
 	xercesc/dom/impl/DOMLSInputImpl.hpp \
 	xercesc/dom/impl/DOMLSOutputImpl.hpp \
+	xercesc/dom/impl/DOMXPathExpressionImpl.hpp \
+	xercesc/dom/impl/DOMXPathNSResolverImpl.hpp \
+	xercesc/dom/impl/DOMXPathResultImpl.hpp \
 	xercesc/dom/impl/XSDElementNSImpl.hpp
 							  
 domimpl_sources	= \
@@ -425,6 +428,9 @@ domimpl_sources	= \
 	xercesc/dom/impl/DOMLSSerializerImpl.cpp \
 	xercesc/dom/impl/DOMLSInputImpl.cpp \
 	xercesc/dom/impl/DOMLSOutputImpl.cpp \
+	xercesc/dom/impl/DOMXPathExpressionImpl.cpp \
+	xercesc/dom/impl/DOMXPathNSResolverImpl.cpp \
+	xercesc/dom/impl/DOMXPathResultImpl.cpp \
 	xercesc/dom/impl/XSDElementNSImpl.cpp
 
 
diff --git a/src/xercesc/NLS/EN_US/XMLErrList_EN_US.Xml b/src/xercesc/NLS/EN_US/XMLErrList_EN_US.Xml
index 6e9fc7a4d..7ec16b38b 100644
--- a/src/xercesc/NLS/EN_US/XMLErrList_EN_US.Xml
+++ b/src/xercesc/NLS/EN_US/XMLErrList_EN_US.Xml
@@ -871,6 +871,11 @@
             <Message Id="DOMLSEXCEPTION_ERRX" Text="Just an index"/>
             <Message Id="PARSE_ERR" Text="An attempt was made to load a document, or an XML Fragment, using DOMLSParser and the processing has been stopped"/>
             <Message Id="SERIALIZE_ERR" Text="An attempt was made to serialize a DOMNode using DOMLSSerializer and the processing has been stopped"/>
+<!--The following are DOMXPathException error text, same order as DOMXPathException::ExceptionCode enum -->
+<!--DOMXPATHEXCEPTION_ERRX is not an error, it's just used to indicate the start of DOMXPathException::ExceptionCode enum -->
+            <Message Id="DOMXPATHEXCEPTION_ERRX" Text="Just an index"/>
+            <Message Id="INVALID_EXPRESSION_ERR" Text="The expression has a syntax error, or contains XPath features not supported by the XPath for XMLSchema syntax"/>
+            <Message Id="TYPE_ERR" Text="The requested result type is not supported"/>
 <!--The following are other messages related to DOM -->
 <!--Messages used by DOMLSSerializer -->
             <Message Id="Writer_NestedCDATA" Text="Nested CDATA sections"/>
diff --git a/src/xercesc/dom/DOMLSException.cpp b/src/xercesc/dom/DOMLSException.cpp
index c49a99cd3..b31cde694 100644
--- a/src/xercesc/dom/DOMLSException.cpp
+++ b/src/xercesc/dom/DOMLSException.cpp
@@ -26,7 +26,6 @@ XERCES_CPP_NAMESPACE_BEGIN
 
 DOMLSException::DOMLSException()
 : DOMException()
-, code((LSExceptionCode) 0)
 {      
 }
 
@@ -34,13 +33,11 @@ DOMLSException::DOMLSException(    LSExceptionCode              exCode
                                  ,       short                  messageCode
                                  ,       MemoryManager* const   memoryManager)
 : DOMException(exCode, messageCode?messageCode:XMLDOMMsg::DOMLSEXCEPTION_ERRX+exCode-DOMLSException::PARSE_ERR+1, memoryManager)
-, code(exCode)
 {  
 }
 
 DOMLSException::DOMLSException(const DOMLSException &other)
 : DOMException(other)
-, code(other.code)
 {
 }
 
diff --git a/src/xercesc/dom/DOMLSException.hpp b/src/xercesc/dom/DOMLSException.hpp
index d56de2635..5e055e48a 100644
--- a/src/xercesc/dom/DOMLSException.hpp
+++ b/src/xercesc/dom/DOMLSException.hpp
@@ -111,44 +111,6 @@ public:
     virtual ~DOMLSException();
     //@}
 
-    // -----------------------------------------------------------------------
-    //  Getter
-    // -----------------------------------------------------------------------
-    inline const XMLCh* getMessage()    const;
-
-    // -----------------------------------------------------------------------
-    //  Class Types
-    // -----------------------------------------------------------------------
-    /** @name Public variables */
-    //@{
-	 /**
-	  * A code value, from the set defined by the LSExceptionCode enum,
-      * indicating the type of error that occured.
-      */
-    LSExceptionCode   code;
-
-	 /**
-	  * A string value.  Applications may use this field to hold an error
-      * message.  The field value is not set by the DOM implementation,
-      * meaning that the string will be empty when an exception is first
-      * thrown.
-	  */
-    const XMLCh *msg;
-    //@}
-
-protected:
-
-    MemoryManager*  fMemoryManager;
-
-private:
-
-	 /**
-	  * A boolean value.  
-      *   If the message is provided by the applications, it is not adopted.
-      *   If the message is resolved by the DOM implementation, it is owned.
-	  */
-    bool            fMsgOwned;
-
 private:
     // -----------------------------------------------------------------------
     // Unimplemented constructors and operators
@@ -156,11 +118,6 @@ private:
     DOMLSException & operator = (const DOMLSException &);
 };
 
-inline const XMLCh* DOMLSException::getMessage() const
-{
-    return msg;
-}
-
 XERCES_CPP_NAMESPACE_END
 
 #endif
diff --git a/src/xercesc/dom/DOMXPathEvaluator.hpp b/src/xercesc/dom/DOMXPathEvaluator.hpp
index d63b39e8e..607d7f535 100644
--- a/src/xercesc/dom/DOMXPathEvaluator.hpp
+++ b/src/xercesc/dom/DOMXPathEvaluator.hpp
@@ -75,7 +75,7 @@ public:
     //@}
 
     // -----------------------------------------------------------------------
-    // Virtual DOMDocument interface
+    // Virtual DOMXPathEvaluator interface
     // -----------------------------------------------------------------------
     /** @name Functions introduced in DOM Level 3 */
     //@{
@@ -92,7 +92,7 @@ public:
      * prefix within the expression will result in <code>DOMException</code> being thrown with the
      * code NAMESPACE_ERR.
      * @return <code>XPathExpression</code> The compiled form of the XPath expression.
-     * @exception <code>XPathException</code>
+     * @exception <code>DOMXPathException</code>
      * INVALID_EXPRESSION_ERR: Raised if the expression is not legal according to the 
      * rules of the <code>DOMXPathEvaluator</code>.
      * @exception DOMException
@@ -140,25 +140,25 @@ public:
      * <code>DOMException</code> being thrown with the code NAMESPACE_ERR.
      * @param type of type unsigned short - If a specific type is specified, then 
      * the result will be returned as the corresponding type.
-     * For XPath 1.0 results, this must be one of the codes of the <code>XPathResult</code>
+     * For XPath 1.0 results, this must be one of the codes of the <code>DOMXPathResult</code>
      * interface.
      * @param result of type void* - The result specifies a specific result object
      * which may be reused and returned by this method. If this is specified as 
      * null or the implementation does not reuse the specified result, a new result
      * object will be constructed and returned.
-     * For XPath 1.0 results, this object will be of type <code>XPathResult</code>.
+     * For XPath 1.0 results, this object will be of type <code>DOMXPathResult</code>.
      * @return void* The result of the evaluation of the XPath expression.
-     * For XPath 1.0 results, this object will be of type <code>XPathResult</code>.
-     * @exception <code>XPathException</code>
+     * For XPath 1.0 results, this object will be of type <code>DOMXPathResult</code>.
+     * @exception <code>DOMXPathException</code>
      * INVALID_EXPRESSION_ERR: Raised if the expression is not legal 
      * according to the rules of the <code>DOMXPathEvaluator</code>
      * TYPE_ERR: Raised if the result cannot be converted to return the specified type.
-     * @exception DOMException
+     * @exception <code>DOMException</code>
      * NAMESPACE_ERR: Raised if the expression contains namespace prefixes 
      * which cannot be resolved by the specified <code>XPathNSResolver</code>.
-     * WRONG_DOCUMENT_ERR: The Node is from a document that is not supported 
+     * WRONG_DOCUMENT_ERR: The DOMNode is from a document that is not supported 
      * by this <code>DOMXPathEvaluator</code>.
-     * NOT_SUPPORTED_ERR: The Node is not a type permitted as an XPath context 
+     * NOT_SUPPORTED_ERR: The DOMNode is not a type permitted as an XPath context 
      * node or the request type is not permitted by this <code>DOMXPathEvaluator</code>.
      */
     virtual void* evaluate(const XMLCh *expression, DOMNode *contextNode, const DOMXPathNSResolver *resolver, 
diff --git a/src/xercesc/dom/DOMXPathException.cpp b/src/xercesc/dom/DOMXPathException.cpp
index 05caaad6b..b9b2fb8b9 100644
--- a/src/xercesc/dom/DOMXPathException.cpp
+++ b/src/xercesc/dom/DOMXPathException.cpp
@@ -17,28 +17,31 @@
 
 
 #include "DOMXPathException.hpp"
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/XMLMsgLoader.hpp>
+#include <xercesc/util/XMLDOMMsg.hpp>
+#include "impl/DOMImplementationImpl.hpp"
 
 XERCES_CPP_NAMESPACE_BEGIN
 
 
 DOMXPathException::DOMXPathException()
-: code((ExceptionCode) 0)
-, msg(0)
+: DOMException()
 {
 }
 
 
-DOMXPathException::DOMXPathException(short exCode, const XMLCh *message)
-: code((ExceptionCode) exCode)
-, msg(message)
+DOMXPathException::DOMXPathException(        short                 exCode
+                                     ,       short                 messageCode
+                                     ,       MemoryManager* const  memoryManager)
+: DOMException(exCode, messageCode?messageCode:XMLDOMMsg::DOMXPATHEXCEPTION_ERRX+exCode-DOMXPathException::INVALID_EXPRESSION_ERR+1, memoryManager)
 {
 }
 
 
 DOMXPathException::DOMXPathException(const DOMXPathException &other)
-: code(other.code)
-, msg(other.msg)
-{        
+: DOMException(other)
+{
 }
 
 
diff --git a/src/xercesc/dom/DOMXPathException.hpp b/src/xercesc/dom/DOMXPathException.hpp
index 8aebd1d2a..310a5081d 100644
--- a/src/xercesc/dom/DOMXPathException.hpp
+++ b/src/xercesc/dom/DOMXPathException.hpp
@@ -18,14 +18,14 @@
  * limitations under the License.
  */
 
-#include <xercesc/util/XercesDefs.hpp>
+#include <xercesc/dom/DOMException.hpp>
 
 XERCES_CPP_NAMESPACE_BEGIN
 
 /**
  * @since DOM Level 3
  */
-class CDOM_EXPORT DOMXPathException
+class CDOM_EXPORT DOMXPathException : public DOMException
 {
 public:
     // -----------------------------------------------------------------------
@@ -45,7 +45,10 @@ public:
       * @param code The error code which indicates the exception
       * @param message The string containing the error message
       */
-    DOMXPathException(short code, const XMLCh *message);
+    DOMXPathException( short                 code
+                     , short                 messageCode = 0
+                     , MemoryManager* const  memoryManager = XMLPlatformUtils::fgMemoryManager
+                     );
 
     /**
       * Copy constructor.
@@ -75,7 +78,7 @@ public:
      * ExceptionCode
      * INVALID_EXPRESSION_ERR If the expression has a syntax error or otherwise
      * is not a legal expression according to the rules of the specific 
-     * <code>XPathEvaluator</code> or contains specialized extension functions
+     * <code>DOMXPathEvaluator</code> or contains specialized extension functions
      * or variables not supported by this implementation.
      * TYPE_ERR If the expression cannot be converted to return the specified type.
      */
@@ -85,26 +88,6 @@ public:
 	};
     //@}
 
-    // -----------------------------------------------------------------------
-    //  Class Types
-    // -----------------------------------------------------------------------
-    /** @name Public variables */
-    //@{
-	 /**
-	  * A code value, from the set defined by the ExceptionCode enum,
-     * indicating the type of error that occured.
-     */
-    ExceptionCode   code;
-
-	 /**
-	  * A string value.  Applications may use this field to hold an error
-     *  message.  The field value is not set by the DOM implementation,
-     *  meaning that the string will be empty when an exception is first
-     *  thrown.
-	  */
-    const XMLCh *msg;
-    //@}
-
 private:
     // -----------------------------------------------------------------------
     // Unimplemented constructors and operators
diff --git a/src/xercesc/dom/DOMXPathExpression.hpp b/src/xercesc/dom/DOMXPathExpression.hpp
index 3aa1e1c48..2a1dd841c 100644
--- a/src/xercesc/dom/DOMXPathExpression.hpp
+++ b/src/xercesc/dom/DOMXPathExpression.hpp
@@ -63,7 +63,7 @@ public:
     //@}
 
     // -----------------------------------------------------------------------
-    // Virtual DOMDocument interface
+    // Virtual DOMXPathExpression interface
     // -----------------------------------------------------------------------
     /** @name Functions introduced in DOM Level 3 */
     //@{  
@@ -82,25 +82,40 @@ public:
      * serve as the XPath context.
      * @param type of type unsigned short If a specific type is specified, then the result
      * will be coerced to return the specified type relying on XPath conversions and fail 
-     * if the desired coercion is not possible. This must be one of the type codes of <code>XPathResult</code>.
+     * if the desired coercion is not possible. This must be one of the type codes of <code>DOMXPathResult</code>.
      * @param result of type void* The result specifies a specific result object which
      * may be reused and returned by this method. If this is specified as nullor the 
      * implementation does not reuse the specified result, a new result object will be constructed
      * and returned.
-     * For XPath 1.0 results, this object will be of type <code>XPathResult</code>.
+     * For XPath 1.0 results, this object will be of type <code>DOMXPathResult</code>.
      * @return void* The result of the evaluation of the XPath expression.
-     * For XPath 1.0 results, this object will be of type <code>XPathResult</code>.
-     * @exception <code>XPathException</code>
+     * For XPath 1.0 results, this object will be of type <code>DOMXPathResult</code>.
+     * @exception <code>DOMXPathException</code>
      * TYPE_ERR: Raised if the result cannot be converted to return the specified type.
      * @exception <code>DOMException</code>
      * WRONG_DOCUMENT_ERR: The <code>DOMNode</code> is from a document that is not supported by 
      * the <code>XPathEvaluator</code> that created this <code>DOMXPathExpression</code>.
-     * NOT_SUPPORTED_ERR: The Node is not a type permitted as an XPath context node or the 
+     * NOT_SUPPORTED_ERR: The DOMNode is not a type permitted as an XPath context node or the 
      * request type is not permitted by this <code>DOMXPathExpression</code>.
      */
 
     virtual void*          evaluate(DOMNode *contextNode, unsigned short type, void* result) const = 0;
     //@}
+
+    // -----------------------------------------------------------------------
+    //  Non-standard Extension
+    // -----------------------------------------------------------------------
+    /** @name Non-standard Extension */
+    //@{
+    /**
+     * Called to indicate that this DOMXPathExpression is no longer in use
+     * and that the implementation may relinquish any resources associated with it.
+     *
+     * Access to a released object will lead to unexpected result.
+     */
+    virtual void              release() const = 0;
+    //@}
+
 };
 
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/dom/DOMXPathNamespace.hpp b/src/xercesc/dom/DOMXPathNamespace.hpp
index 9c841f84d..b3f378047 100644
--- a/src/xercesc/dom/DOMXPathNamespace.hpp
+++ b/src/xercesc/dom/DOMXPathNamespace.hpp
@@ -90,7 +90,7 @@ public:
     //@}
 
     // -----------------------------------------------------------------------
-    // Virtual DOMDocument interface
+    // Virtual DOMXPathNamespace interface
     // -----------------------------------------------------------------------
     /** @name Functions introduced in DOM Level 3 */
     //@{
diff --git a/src/xercesc/dom/DOMXPathResult.hpp b/src/xercesc/dom/DOMXPathResult.hpp
index 3df6501e5..414c12d52 100644
--- a/src/xercesc/dom/DOMXPathResult.hpp
+++ b/src/xercesc/dom/DOMXPathResult.hpp
@@ -149,7 +149,7 @@ public:
 
 
     // -----------------------------------------------------------------------
-    // Virtual DOMDocument interface
+    // Virtual DOMXPathResult interface
     // -----------------------------------------------------------------------
     /** @name Functions introduced in DOM Level 3 */
     //@{
@@ -159,7 +159,7 @@ public:
      * Returns the boolean value of this result
      * @return booleanValue of type boolean, readonly
      * The value of this boolean result.
-     * @exception XPathException
+     * @exception DOMXPathException
      * TYPE_ERR: raised if resultType is not BOOLEAN_TYPE.
      */
 	virtual bool getBooleanValue() const = 0;
@@ -170,8 +170,6 @@ public:
      * Signifies that the iterator has become invalid. True if resultType is 
      * UNORDERED_NODE_ITERATOR_TYPE or ORDERED_NODE_ITERATOR_TYPE and the 
      * document has been modified since this result was returned.
-     * @exception XPathException 
-     * TYPE_ERR: raised if resultType is not NUMBER_TYPE.
      */
 	virtual bool getInvalidIteratorState() const = 0;
 
@@ -182,7 +180,7 @@ public:
      * binding does not directly support the exact IEEE 754 result of the XPath 
      * expression, then it is up to the definition of the binding to specify how 
      * the XPath number is converted to the native binding number.
-     * @exception XPathException
+     * @exception DOMXPathException
      * TYPE_ERR: raised if resultType is not NUMBER_TYPE.
      */
 	virtual double getNumberValue() const = 0;
@@ -191,8 +189,6 @@ public:
      * Returns the result type of this result
      * @return resultType 
      * A code representing the type of this result, as defined by the type constants.       
-     * @exception XPathException
-     * TYPE_ERR: raised if resultType is not ANY_UNORDERED_NODE_TYPE or FIRST_ORDERED_NODE_TYPE.
      */
 	virtual short getResultType() const = 0;
     	
@@ -200,7 +196,7 @@ public:
      * Returns the single node value of this result
      * @return singleNodeValue 
      * The value of this single node result, which may be null.
-     * @exception XPathException
+     * @exception DOMXPathException
      * TYPE_ERR: raised if resultType is not ANY_UNORDERED_NODE_TYPE or FIRST_ORDERED_NODE_TYPE.
      */
 	virtual DOMNode *getSingleNodeValue() const = 0;
@@ -210,7 +206,7 @@ public:
      * @return snapshotLength 
      * The number of nodes in the result snapshot. Valid values for snapshotItem indices 
      * are 0 to snapshotLength-1 inclusive.
-     * @exception XPathException
+     * @exception DOMXPathException
      * TYPE_ERR: raised if resultType is not UNORDERED_NODE_SNAPSHOT_TYPE or 
      * ORDERED_NODE_SNAPSHOT_TYPE.        
      */
@@ -220,15 +216,15 @@ public:
      * Returns the string value of this result
      * @return stringValue 
      * The value of this string result.
-     * @exception XPathException
+     * @exception DOMXPathException
      * TYPE_ERR: raised if resultType is not STRING_TYPE.
      */
 	virtual const XMLCh* getStringValue() const = 0;
     
     /**
-     * Iterates and returns the next node from the node set or nullif there are no more nodes.
+     * Iterates and returns the next node from the node set or <code>null</code> if there are no more nodes.
      * @return the next node.
-     * @exception XPathException
+     * @exception DOMXPathException
      * TYPE_ERR: raised if resultType is not UNORDERED_NODE_ITERATOR_TYPE or ORDERED_NODE_ITERATOR_TYPE.
      * @exception DOMException
      * INVALID_STATE_ERR: The document has been mutated since the result was returned.	
@@ -242,12 +238,26 @@ public:
      * to the current document if it is mutated.
      * @param index of type unsigned long - Index into the snapshot collection.
      * @return The node at the indexth position in the NodeList, or null if that is not a valid index.
-     * @exception XPathException
+     * @exception DOMXPathException
      * TYPE_ERR: raised if resultType is not UNORDERED_NODE_SNAPSHOT_TYPE or ORDERED_NODE_SNAPSHOT_TYPE.	
      */
 	virtual DOMNode* snapshotItem(unsigned long index) const = 0;
 
     //@}
+
+    // -----------------------------------------------------------------------
+    //  Non-standard Extension
+    // -----------------------------------------------------------------------
+    /** @name Non-standard Extension */
+    //@{
+    /**
+     * Called to indicate that this DOMXPathResult is no longer in use
+     * and that the implementation may relinquish any resources associated with it.
+     *
+     * Access to a released object will lead to unexpected result.
+     */
+    virtual void              release() const = 0;
+    //@}
 };
 
 XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/dom/impl/DOMDocumentImpl.cpp b/src/xercesc/dom/impl/DOMDocumentImpl.cpp
index 1a9e0b00b..d55fe97dd 100644
--- a/src/xercesc/dom/impl/DOMDocumentImpl.cpp
+++ b/src/xercesc/dom/impl/DOMDocumentImpl.cpp
@@ -42,6 +42,8 @@
 #include "DOMNodeIDMap.hpp"
 #include "DOMRangeImpl.hpp"
 #include "DOMTypeInfoImpl.hpp"
+#include "DOMXPathExpressionImpl.hpp"
+#include "DOMXPathNSResolverImpl.hpp"
 
 #include <xercesc/dom/DOMImplementation.hpp>
 #include <xercesc/util/XMLChar.hpp>
@@ -420,24 +422,23 @@ void DOMDocumentImpl::removeNodeIterator(DOMNodeIteratorImpl* nodeIterator)
 }
 
 
-const DOMXPathExpression* DOMDocumentImpl::createExpression(const XMLCh *, const DOMXPathNSResolver *)
+const DOMXPathExpression* DOMDocumentImpl::createExpression(const XMLCh * expression, const DOMXPathNSResolver *resolver)
 {
-    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager());
-    return 0;
+    return new (getMemoryManager()) DOMXPathExpressionImpl(expression, resolver, getMemoryManager());
 }
 
-const DOMXPathNSResolver* DOMDocumentImpl::createNSResolver(DOMNode *)
-
+const DOMXPathNSResolver* DOMDocumentImpl::createNSResolver(DOMNode *nodeResolver)
 {
-    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager());
-    return 0;
+    return new (this) DOMXPathNSResolverImpl(nodeResolver);
 }
 
-void* DOMDocumentImpl::evaluate(const XMLCh *, DOMNode *, const DOMXPathNSResolver *, 
-                           unsigned short, void* ) 
+void* DOMDocumentImpl::evaluate(const XMLCh *expression, DOMNode *contextNode, const DOMXPathNSResolver *resolver, 
+                           unsigned short type, void* result) 
 {
-    throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, getMemoryManager());
-    return 0;
+    const DOMXPathExpression* expr=createExpression(expression, resolver);
+    result=expr->evaluate(contextNode, type, result);
+    expr->release();
+    return result;
 }
 
 
diff --git a/src/xercesc/dom/impl/DOMImplementationImpl.cpp b/src/xercesc/dom/impl/DOMImplementationImpl.cpp
index 1c6d342e6..9e1cc41ac 100644
--- a/src/xercesc/dom/impl/DOMImplementationImpl.cpp
+++ b/src/xercesc/dom/impl/DOMImplementationImpl.cpp
@@ -61,6 +61,8 @@ static const XMLCh  gRange[] =     // Points to "Range"
         {chLatin_R, chLatin_a, chLatin_n, chLatin_g, chLatin_e, chNull};
 static const XMLCh  gLS[] =     // Points to "LS"
         {chLatin_L, chLatin_S, chNull};
+static const XMLCh  gXPath[] =     // Points to "XPath"
+        {chLatin_X, chLatin_P, chLatin_a, chLatin_t, chLatin_h, chNull};
 
 
 // -----------------------------------------------------------------------
@@ -211,6 +213,10 @@ bool  DOMImplementationImpl::hasFeature(const  XMLCh * feature,  const  XMLCh *
         && (anyVersion || version3_0))
         return true;
 
+    if (XMLString::compareIStringASCII(feature, gXPath) == 0
+        && (anyVersion || version3_0))
+        return true;
+
     return false;
 }
 
diff --git a/src/xercesc/dom/impl/DOMXPathExpressionImpl.cpp b/src/xercesc/dom/impl/DOMXPathExpressionImpl.cpp
new file mode 100644
index 000000000..77ed5a9f9
--- /dev/null
+++ b/src/xercesc/dom/impl/DOMXPathExpressionImpl.cpp
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include "DOMXPathExpressionImpl.hpp"
+#include "DOMXPathResultImpl.hpp"
+#include <xercesc/validators/schema/identity/XercesXPath.hpp>
+#include <xercesc/validators/schema/identity/XPathMatcher.hpp>
+#include <xercesc/validators/schema/identity/XPathException.hpp>
+#include <xercesc/validators/schema/SchemaElementDecl.hpp>
+#include <xercesc/util/StringPool.hpp>
+#include <xercesc/util/OutOfMemoryException.hpp>
+#include <xercesc/dom/DOMXPathException.hpp>
+#include <xercesc/dom/DOM.hpp>
+
+XERCES_CPP_NAMESPACE_BEGIN
+
+class WrapperForXPathNSResolver : public XercesNamespaceResolver
+{
+public:
+    WrapperForXPathNSResolver(XMLStringPool* pool, const DOMXPathNSResolver *resolver, MemoryManager* const manager) : 
+      fStringPool(pool), 
+      fResolver(resolver),
+      fMemoryManager(manager)
+    {
+    }
+
+    virtual unsigned int getNamespaceForPrefix(const XMLCh* const prefix)
+    {
+        if(fResolver==NULL)
+            throw DOMException(DOMException::NAMESPACE_ERR, 0, fMemoryManager);
+        const XMLCh* nsUri=fResolver->lookupNamespaceURI(prefix);
+        if(nsUri==NULL)
+            throw DOMException(DOMException::NAMESPACE_ERR, 0, fMemoryManager);
+        return fStringPool->addOrFind(nsUri);
+    }
+
+protected:
+    XMLStringPool*              fStringPool;
+    const DOMXPathNSResolver *  fResolver;
+    MemoryManager* const        fMemoryManager;
+};
+
+
+typedef JanitorMemFunCall<DOMXPathExpressionImpl>     CleanupType;
+
+DOMXPathExpressionImpl::DOMXPathExpressionImpl(const XMLCh *expression, const DOMXPathNSResolver *resolver, MemoryManager* const manager) :
+ fStringPool(NULL),
+ fParsedExpression(NULL),
+ fExpression(NULL),
+ fMoveToRoot(false),
+ fMemoryManager(manager)
+{
+    if(expression==NULL || *expression==0)
+        throw DOMXPathException(DOMXPathException::INVALID_EXPRESSION_ERR, 0, fMemoryManager);
+
+    CleanupType cleanup(this, &DOMXPathExpressionImpl::cleanUp);
+    fStringPool = new (fMemoryManager) XMLStringPool(109, fMemoryManager);
+    // XercesPath will complain if the expression starts with '/', add a "." in front of it and start from the document root
+    if(*expression==chForwardSlash)
+    {
+        fExpression=(XMLCh*)fMemoryManager->allocate((XMLString::stringLen(expression)+2)*sizeof(XMLCh));
+        *fExpression = chPeriod;
+        *(fExpression+1) = chNull;
+        XMLString::catString(fExpression, expression);
+        fMoveToRoot=true;
+    }
+    else
+        fExpression=XMLString::replicate(expression);
+
+    try
+    {
+        WrapperForXPathNSResolver wrappedResolver(fStringPool, resolver, fMemoryManager);
+        fParsedExpression = new (fMemoryManager) XercesXPath(fExpression, fStringPool, &wrappedResolver, 0, true, fMemoryManager);
+    }
+    catch(const XPathException& )
+    {
+        throw DOMXPathException(DOMXPathException::INVALID_EXPRESSION_ERR, 0, fMemoryManager);
+    }
+    catch(const OutOfMemoryException&)
+    {
+        cleanup.release();
+
+        throw;
+    }
+
+    cleanup.release();
+}
+
+DOMXPathExpressionImpl::~DOMXPathExpressionImpl()
+{
+    cleanUp();
+}
+
+void DOMXPathExpressionImpl::cleanUp() 
+{
+    XMLString::release(&fExpression, fMemoryManager);
+    delete fParsedExpression;
+    delete fStringPool;
+}
+
+void* DOMXPathExpressionImpl::evaluate(DOMNode *contextNode, unsigned short type, void* result) const
+{
+    if(type!=DOMXPathResult::FIRST_ORDERED_NODE_TYPE && type!=DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE && 
+       type!=DOMXPathResult::ANY_UNORDERED_NODE_TYPE && type!=DOMXPathResult::UNORDERED_NODE_SNAPSHOT_TYPE)
+        throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+
+    if(contextNode==NULL || contextNode->getNodeType()!=DOMNode::ELEMENT_NODE)
+        throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);
+
+    DOMXPathResultImpl* r=(DOMXPathResultImpl*)result;
+    if(r==NULL)
+        r=new (fMemoryManager) DOMXPathResultImpl(type, fMemoryManager);
+    else
+        r->reset(type);
+
+    XPathMatcher matcher(fParsedExpression, fMemoryManager);
+    matcher.startDocumentFragment();
+
+    if(fMoveToRoot)
+    {
+        contextNode=contextNode->getOwnerDocument();
+        if(contextNode==NULL)
+            throw DOMException(DOMException::NOT_SUPPORTED_ERR, 0, fMemoryManager);
+
+        QName qName(contextNode->getNodeName(), 0, fMemoryManager);
+        SchemaElementDecl elemDecl(&qName);
+        RefVectorOf<XMLAttr> attrList(0, true, fMemoryManager);
+        matcher.startElement(elemDecl, 0, XMLUni::fgZeroLenString, attrList, 0);
+        DOMNode* child=contextNode->getFirstChild();
+        while(child)
+        {
+            if(child->getNodeType()==DOMNode::ELEMENT_NODE)
+                testNode(&matcher, r, (DOMElement*)child);
+            child=child->getNextSibling();
+        }
+        matcher.endElement(elemDecl, XMLUni::fgZeroLenString);
+    }
+    else
+        testNode(&matcher, r, (DOMElement*)contextNode); 
+    return r;
+}
+
+bool DOMXPathExpressionImpl::testNode(XPathMatcher* matcher, DOMXPathResultImpl* result, DOMElement *node) const
+{
+    int uriId=fStringPool->addOrFind(node->getNamespaceURI());
+    QName qName(node->getNodeName(), uriId, fMemoryManager);
+    SchemaElementDecl elemDecl(&qName);
+    DOMNamedNodeMap* attrMap=node->getAttributes();
+    unsigned int attrCount = attrMap->getLength();
+    RefVectorOf<XMLAttr> attrList(attrCount, true, fMemoryManager);
+    for(unsigned int i=0;i<attrCount;i++)
+    {
+        DOMAttr* attr=(DOMAttr*)attrMap->item(i);
+        attrList.addElement(new (fMemoryManager) XMLAttr(fStringPool->addOrFind(attr->getNamespaceURI()),
+                                                         attr->getNodeName(),
+                                                         attr->getNodeValue(),
+                                                         XMLAttDef::CData,
+                                                         attr->getSpecified(),
+                                                         fMemoryManager,
+                                                         NULL,
+                                                         true));
+    }
+    matcher->startElement(elemDecl, uriId, node->getPrefix(), attrList, attrCount);
+    int nMatch=matcher->isMatched();
+    if(nMatch!=0 && nMatch!=XPathMatcher::XP_MATCHED_DP)
+    {
+        result->addResult(node);
+        if(result->getResultType()==DOMXPathResult::ANY_UNORDERED_NODE_TYPE || result->getResultType()==DOMXPathResult::FIRST_ORDERED_NODE_TYPE)
+            return true;    // abort navigation, we found one result
+    }
+
+    if(nMatch==0 || nMatch==XPathMatcher::XP_MATCHED_D || nMatch==XPathMatcher::XP_MATCHED_DP) 
+    {
+        DOMNode* child=node->getFirstChild();
+        while(child)
+        {
+            if(child->getNodeType()==DOMNode::ELEMENT_NODE)
+                if(testNode(matcher, result, (DOMElement*)child))
+                    return true;
+            child=child->getNextSibling();
+        }
+    }
+    matcher->endElement(elemDecl, XMLUni::fgZeroLenString);
+    return false;
+}
+
+void DOMXPathExpressionImpl::release() const
+{
+    DOMXPathExpressionImpl* me=(DOMXPathExpressionImpl*)this;
+    delete me;
+}
+
+XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/dom/impl/DOMXPathExpressionImpl.hpp b/src/xercesc/dom/impl/DOMXPathExpressionImpl.hpp
new file mode 100644
index 000000000..da42dc5bd
--- /dev/null
+++ b/src/xercesc/dom/impl/DOMXPathExpressionImpl.hpp
@@ -0,0 +1,59 @@
+#ifndef DOMXPathExpressionImpl_HEADER_GUARD_
+#define DOMXPathExpressionImpl_HEADER_GUARD_
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include <xercesc/util/XMemory.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/dom/DOMXPathExpression.hpp>
+
+XERCES_CPP_NAMESPACE_BEGIN
+
+class DOMElement;
+class XercesXPath;
+class XPathMatcher;
+class DOMXPathResultImpl;
+class DOMXPathNSResolver;
+class XMLStringPool;
+
+class CDOM_EXPORT DOMXPathExpressionImpl :  public XMemory,
+                                            public DOMXPathExpression
+{
+public:
+    DOMXPathExpressionImpl(const XMLCh *expression, const DOMXPathNSResolver *resolver, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
+    virtual ~DOMXPathExpressionImpl();
+
+    virtual void* evaluate(DOMNode *contextNode, unsigned short type, void* result) const;
+
+    virtual void release() const;
+
+protected:
+    bool testNode(XPathMatcher* matcher, DOMXPathResultImpl* result, DOMElement *node) const;
+    void cleanUp();
+
+    XMLStringPool*              fStringPool;
+    XercesXPath*                fParsedExpression;
+    XMLCh*                      fExpression;
+    bool                        fMoveToRoot;
+
+    MemoryManager* const        fMemoryManager;
+};
+
+XERCES_CPP_NAMESPACE_END
+
+#endif
diff --git a/src/xercesc/dom/impl/DOMXPathNSResolverImpl.cpp b/src/xercesc/dom/impl/DOMXPathNSResolverImpl.cpp
new file mode 100644
index 000000000..1029b4669
--- /dev/null
+++ b/src/xercesc/dom/impl/DOMXPathNSResolverImpl.cpp
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include "DOMXPathNSResolverImpl.hpp"
+#include <xercesc/dom/DOMNode.hpp>
+#include <xercesc/util/XMLString.hpp>
+
+XERCES_CPP_NAMESPACE_BEGIN
+
+DOMXPathNSResolverImpl::DOMXPathNSResolverImpl(DOMNode *nodeResolver):
+ fResolverNode(nodeResolver)
+{
+}
+
+const XMLCh* DOMXPathNSResolverImpl::lookupNamespaceURI(const XMLCh* prefix) const
+{
+    if (XMLString::equals(prefix, XMLUni::fgXMLString))
+        return XMLUni::fgXMLURIName;
+    if(fResolverNode)
+        return fResolverNode->lookupNamespaceURI(prefix);
+    return NULL;
+}
+
+const XMLCh* DOMXPathNSResolverImpl::lookupPrefix(const XMLCh* URI) const
+{
+    if (XMLString::equals(URI, XMLUni::fgXMLURIName))
+        return XMLUni::fgXMLString;
+    if(fResolverNode)
+        return fResolverNode->lookupPrefix(URI);
+    return NULL;
+}
+
+XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/dom/impl/DOMXPathNSResolverImpl.hpp b/src/xercesc/dom/impl/DOMXPathNSResolverImpl.hpp
new file mode 100644
index 000000000..9ab8f2d65
--- /dev/null
+++ b/src/xercesc/dom/impl/DOMXPathNSResolverImpl.hpp
@@ -0,0 +1,43 @@
+#ifndef DOMXPathNSResolverImpl_HEADER_GUARD_
+#define DOMXPathNSResolverImpl_HEADER_GUARD_
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include <xercesc/util/XercesDefs.hpp>
+#include <xercesc/dom/DOMXPathNSResolver.hpp>
+
+XERCES_CPP_NAMESPACE_BEGIN
+
+class DOMNode;
+
+class CDOM_EXPORT DOMXPathNSResolverImpl : public DOMXPathNSResolver
+{
+public:
+    DOMXPathNSResolverImpl(DOMNode *nodeResolver);
+
+    virtual const XMLCh*          lookupNamespaceURI(const XMLCh* prefix) const;
+    virtual const XMLCh*          lookupPrefix(const XMLCh* URI) const;
+
+protected:
+    DOMNode*                    fResolverNode;
+};
+
+XERCES_CPP_NAMESPACE_END
+
+#endif
+
diff --git a/src/xercesc/dom/impl/DOMXPathResultImpl.cpp b/src/xercesc/dom/impl/DOMXPathResultImpl.cpp
new file mode 100644
index 000000000..fccdb0e69
--- /dev/null
+++ b/src/xercesc/dom/impl/DOMXPathResultImpl.cpp
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include "DOMXPathResultImpl.hpp"
+#include <xercesc/dom/DOMNode.hpp>
+#include <xercesc/dom/DOMXPathException.hpp>
+
+XERCES_CPP_NAMESPACE_BEGIN
+
+DOMXPathResultImpl::DOMXPathResultImpl(unsigned short type, MemoryManager* const manager) :
+  fType(type),
+  fMemoryManager(manager)
+{
+    fSnapshot=new (fMemoryManager) RefVectorOf<DOMNode>(13, false, fMemoryManager);
+}
+
+DOMXPathResultImpl::~DOMXPathResultImpl()
+{
+    delete fSnapshot;
+}
+
+void DOMXPathResultImpl::reset(unsigned short type)
+{
+    fType=type;
+    fSnapshot->removeAllElements();
+}
+
+void DOMXPathResultImpl::addResult(DOMNode* node)
+{
+    fSnapshot->addElement(node);
+}
+
+bool DOMXPathResultImpl::getBooleanValue() const
+{
+    throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+}
+
+double DOMXPathResultImpl::getNumberValue() const
+{
+    throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+}
+
+const XMLCh* DOMXPathResultImpl::getStringValue() const
+{
+    throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+}
+
+DOMNode* DOMXPathResultImpl::iterateNext() const
+{
+    throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+}
+
+bool DOMXPathResultImpl::getInvalidIteratorState() const
+{
+    return false;
+}
+
+short DOMXPathResultImpl::getResultType() const
+{
+    return fType;
+}
+
+DOMNode *DOMXPathResultImpl::getSingleNodeValue() const
+{
+    if(fType==ANY_UNORDERED_NODE_TYPE || fType==FIRST_ORDERED_NODE_TYPE)
+        if(fSnapshot->size()>0)
+            return fSnapshot->elementAt(0);
+        else
+            return NULL;
+    throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+}
+
+unsigned long DOMXPathResultImpl::getSnapshotLength() const
+{
+    if(fType==UNORDERED_NODE_SNAPSHOT_TYPE || fType==ORDERED_NODE_SNAPSHOT_TYPE)
+        return fSnapshot->size();
+    throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+}
+
+DOMNode* DOMXPathResultImpl::snapshotItem(unsigned long index) const
+{
+    if(fType==UNORDERED_NODE_SNAPSHOT_TYPE || fType==ORDERED_NODE_SNAPSHOT_TYPE)
+        if(fSnapshot->size()>index)
+            return fSnapshot->elementAt(index);
+        else
+            return NULL;
+    throw DOMXPathException(DOMXPathException::TYPE_ERR, 0, fMemoryManager);
+}
+
+void DOMXPathResultImpl::release() const
+{
+    DOMXPathResultImpl* me=(DOMXPathResultImpl*)this;
+    delete me;
+}
+
+XERCES_CPP_NAMESPACE_END
diff --git a/src/xercesc/dom/impl/DOMXPathResultImpl.hpp b/src/xercesc/dom/impl/DOMXPathResultImpl.hpp
new file mode 100644
index 000000000..cb69cdd17
--- /dev/null
+++ b/src/xercesc/dom/impl/DOMXPathResultImpl.hpp
@@ -0,0 +1,57 @@
+#ifndef DOMXPathResultImpl_HEADER_GUARD_
+#define DOMXPathResultImpl_HEADER_GUARD_
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+#include <xercesc/util/XMemory.hpp>
+#include <xercesc/dom/DOMXPathResult.hpp>
+#include <xercesc/util/RefVectorOf.hpp>
+
+XERCES_CPP_NAMESPACE_BEGIN
+
+class CDOM_EXPORT DOMXPathResultImpl :  public XMemory,
+                                        public DOMXPathResult
+{
+public:
+    DOMXPathResultImpl(unsigned short type, MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
+    ~DOMXPathResultImpl();
+
+	virtual bool getBooleanValue() const;
+	virtual bool getInvalidIteratorState() const;
+	virtual double getNumberValue() const;
+	virtual short getResultType() const;
+	virtual DOMNode *getSingleNodeValue() const;
+	virtual unsigned long getSnapshotLength() const;
+	virtual const XMLCh* getStringValue() const;
+	virtual DOMNode* iterateNext() const;
+	virtual DOMNode* snapshotItem(unsigned long index) const;
+
+    virtual void release() const;
+
+    void reset(unsigned short type);
+    void addResult(DOMNode* node);
+
+protected:
+    unsigned short          fType;
+    MemoryManager* const    fMemoryManager;
+    RefVectorOf<DOMNode>*   fSnapshot;
+};
+
+XERCES_CPP_NAMESPACE_END
+
+#endif
diff --git a/src/xercesc/util/MsgLoaders/ICU/resources/en_US.txt b/src/xercesc/util/MsgLoaders/ICU/resources/en_US.txt
index 923dfd648..16fa56882 100644
--- a/src/xercesc/util/MsgLoaders/ICU/resources/en_US.txt
+++ b/src/xercesc/util/MsgLoaders/ICU/resources/en_US.txt
@@ -869,6 +869,9 @@ en_US {
 		"Just an index " ,
 		"An attempt was made to load a document, or an XML Fragment, using DOMLSParser and the processing has been stopped " ,
 		"An attempt was made to serialize a DOMNode using DOMLSSerializer and the processing has been stopped " ,
+		"Just an index " ,
+		"The expression has a syntax error, or contains XPath features not supported by the XPath for XMLSchema syntax " ,
+		"The requested result type is not supported " ,
 		"Nested CDATA sections " ,
 		"Unrepresentable character data " ,
 		"Unrecognized Node Type " ,
diff --git a/src/xercesc/util/MsgLoaders/InMemory/XercesMessages_en_US.hpp b/src/xercesc/util/MsgLoaders/InMemory/XercesMessages_en_US.hpp
index d8d6cfae4..35722ce35 100644
--- a/src/xercesc/util/MsgLoaders/InMemory/XercesMessages_en_US.hpp
+++ b/src/xercesc/util/MsgLoaders/InMemory/XercesMessages_en_US.hpp
@@ -1739,6 +1739,13 @@ const XMLCh gXMLDOMMsgArray[][128] =
   , { 0x0041,0x006E,0x0020,0x0061,0x0074,0x0074,0x0065,0x006D,0x0070,0x0074,0x0020,0x0077,0x0061,0x0073,0x0020,0x006D,0x0061,0x0064,0x0065,0x0020,0x0074,0x006F,0x0020,0x0073,0x0065,0x0072,0x0069,0x0061,0x006C,0x0069,0x007A,0x0065,0x0020,0x0061,0x0020,
       0x0044,0x004F,0x004D,0x004E,0x006F,0x0064,0x0065,0x0020,0x0075,0x0073,0x0069,0x006E,0x0067,0x0020,0x0044,0x004F,0x004D,0x004C,0x0053,0x0053,0x0065,0x0072,0x0069,0x0061,0x006C,0x0069,0x007A,0x0065,0x0072,0x0020,0x0061,0x006E,0x0064,0x0020,0x0074,
       0x0068,0x0065,0x0020,0x0070,0x0072,0x006F,0x0063,0x0065,0x0073,0x0073,0x0069,0x006E,0x0067,0x0020,0x0068,0x0061,0x0073,0x0020,0x0062,0x0065,0x0065,0x006E,0x0020,0x0073,0x0074,0x006F,0x0070,0x0070,0x0065,0x0064,0x00 }
+  , { 0x004A,0x0075,0x0073,0x0074,0x0020,0x0061,0x006E,0x0020,0x0069,0x006E,0x0064,0x0065,0x0078,0x00 }
+  , { 0x0054,0x0068,0x0065,0x0020,0x0065,0x0078,0x0070,0x0072,0x0065,0x0073,0x0073,0x0069,0x006F,0x006E,0x0020,0x0068,0x0061,0x0073,0x0020,0x0061,0x0020,0x0073,0x0079,0x006E,0x0074,0x0061,0x0078,0x0020,0x0065,0x0072,0x0072,0x006F,0x0072,0x002C,0x0020,
+      0x006F,0x0072,0x0020,0x0063,0x006F,0x006E,0x0074,0x0061,0x0069,0x006E,0x0073,0x0020,0x0058,0x0050,0x0061,0x0074,0x0068,0x0020,0x0066,0x0065,0x0061,0x0074,0x0075,0x0072,0x0065,0x0073,0x0020,0x006E,0x006F,0x0074,0x0020,0x0073,0x0075,0x0070,0x0070,
+      0x006F,0x0072,0x0074,0x0065,0x0064,0x0020,0x0062,0x0079,0x0020,0x0074,0x0068,0x0065,0x0020,0x0058,0x0050,0x0061,0x0074,0x0068,0x0020,0x0066,0x006F,0x0072,0x0020,0x0058,0x004D,0x004C,0x0053,0x0063,0x0068,0x0065,0x006D,0x0061,0x0020,0x0073,0x0079,
+      0x006E,0x0074,0x0061,0x0078,0x00 }
+  , { 0x0054,0x0068,0x0065,0x0020,0x0072,0x0065,0x0071,0x0075,0x0065,0x0073,0x0074,0x0065,0x0064,0x0020,0x0072,0x0065,0x0073,0x0075,0x006C,0x0074,0x0020,0x0074,0x0079,0x0070,0x0065,0x0020,0x0069,0x0073,0x0020,0x006E,0x006F,0x0074,0x0020,0x0073,0x0075,
+      0x0070,0x0070,0x006F,0x0072,0x0074,0x0065,0x0064,0x00 }
   , { 0x004E,0x0065,0x0073,0x0074,0x0065,0x0064,0x0020,0x0043,0x0044,0x0041,0x0054,0x0041,0x0020,0x0073,0x0065,0x0063,0x0074,0x0069,0x006F,0x006E,0x0073,0x00 }
   , { 0x0055,0x006E,0x0072,0x0065,0x0070,0x0072,0x0065,0x0073,0x0065,0x006E,0x0074,0x0061,0x0062,0x006C,0x0065,0x0020,0x0063,0x0068,0x0061,0x0072,0x0061,0x0063,0x0074,0x0065,0x0072,0x0020,0x0064,0x0061,0x0074,0x0061,0x00 }
   , { 0x0055,0x006E,0x0072,0x0065,0x0063,0x006F,0x0067,0x006E,0x0069,0x007A,0x0065,0x0064,0x0020,0x004E,0x006F,0x0064,0x0065,0x0020,0x0054,0x0079,0x0070,0x0065,0x00 }
@@ -1749,7 +1756,7 @@ const XMLCh gXMLDOMMsgArray[][128] =
   , { 0x0046,0x005F,0x0045,0x006E,0x0064,0x00 }
 
 };
-const unsigned int gXMLDOMMsgArraySize = 35;
+const unsigned int gXMLDOMMsgArraySize = 38;
 
 XERCES_CPP_NAMESPACE_END
 
diff --git a/src/xercesc/util/MsgLoaders/MsgCatalog/XercesMessages_en_US.Msg b/src/xercesc/util/MsgLoaders/MsgCatalog/XercesMessages_en_US.Msg
index d6d7e298b..d250a8cdf 100644
--- a/src/xercesc/util/MsgLoaders/MsgCatalog/XercesMessages_en_US.Msg
+++ b/src/xercesc/util/MsgLoaders/MsgCatalog/XercesMessages_en_US.Msg
@@ -848,10 +848,13 @@ $set 4
 22  Just an index
 23  An attempt was made to load a document, or an XML Fragment, using DOMLSParser and the processing has been stopped
 24  An attempt was made to serialize a DOMNode using DOMLSSerializer and the processing has been stopped
-25  Nested CDATA sections
-26  Unrepresentable character data
-27  Unrecognized Node Type
-28  Parse may not be called while parsing
-29  Parsing has been aborted by the user
+25  Just an index
+26  The expression has a syntax error, or contains XPath features not supported by the XPath for XMLSchema syntax
+27  The requested result type is not supported
+28  Nested CDATA sections
+29  Unrepresentable character data
+30  Unrecognized Node Type
+31  Parse may not be called while parsing
+32  Parsing has been aborted by the user
 
 
diff --git a/src/xercesc/util/MsgLoaders/Win32/Version.rc b/src/xercesc/util/MsgLoaders/Win32/Version.rc
index 459d0fef4..b466e169d 100644
--- a/src/xercesc/util/MsgLoaders/Win32/Version.rc
+++ b/src/xercesc/util/MsgLoaders/Win32/Version.rc
@@ -950,11 +950,14 @@ BEGIN
     24598             L"\x004A\x0075\x0073\x0074\x0020\x0061\x006E\x0020\x0069\x006E\x0064\x0065\x0078\x00"
     24599             L"\x0041\x006E\x0020\x0061\x0074\x0074\x0065\x006D\x0070\x0074\x0020\x0077\x0061\x0073\x0020\x006D\x0061\x0064\x0065\x0020\x0074\x006F\x0020\x006C\x006F\x0061\x0064\x0020\x0061\x0020\x0064\x006F\x0063\x0075\x006D\x0065\x006E\x0074\x002C\x0020\x006F\x0072\x0020\x0061\x006E\x0020\x0058\x004D\x004C\x0020\x0046\x0072\x0061\x0067\x006D\x0065\x006E\x0074\x002C\x0020\x0075\x0073\x0069\x006E\x0067\x0020\x0044\x004F\x004D\x004C\x0053\x0050\x0061\x0072\x0073\x0065\x0072\x0020\x0061\x006E\x0064\x0020\x0074\x0068\x0065\x0020\x0070\x0072\x006F\x0063\x0065\x0073\x0073\x0069\x006E\x0067\x0020\x0068\x0061\x0073\x0020\x0062\x0065\x0065\x006E\x0020\x0073\x0074\x006F\x0070\x0070\x0065\x0064\x00"
     24600             L"\x0041\x006E\x0020\x0061\x0074\x0074\x0065\x006D\x0070\x0074\x0020\x0077\x0061\x0073\x0020\x006D\x0061\x0064\x0065\x0020\x0074\x006F\x0020\x0073\x0065\x0072\x0069\x0061\x006C\x0069\x007A\x0065\x0020\x0061\x0020\x0044\x004F\x004D\x004E\x006F\x0064\x0065\x0020\x0075\x0073\x0069\x006E\x0067\x0020\x0044\x004F\x004D\x004C\x0053\x0053\x0065\x0072\x0069\x0061\x006C\x0069\x007A\x0065\x0072\x0020\x0061\x006E\x0064\x0020\x0074\x0068\x0065\x0020\x0070\x0072\x006F\x0063\x0065\x0073\x0073\x0069\x006E\x0067\x0020\x0068\x0061\x0073\x0020\x0062\x0065\x0065\x006E\x0020\x0073\x0074\x006F\x0070\x0070\x0065\x0064\x00"
-    24601             L"\x004E\x0065\x0073\x0074\x0065\x0064\x0020\x0043\x0044\x0041\x0054\x0041\x0020\x0073\x0065\x0063\x0074\x0069\x006F\x006E\x0073\x00"
-    24602             L"\x0055\x006E\x0072\x0065\x0070\x0072\x0065\x0073\x0065\x006E\x0074\x0061\x0062\x006C\x0065\x0020\x0063\x0068\x0061\x0072\x0061\x0063\x0074\x0065\x0072\x0020\x0064\x0061\x0074\x0061\x00"
-    24603             L"\x0055\x006E\x0072\x0065\x0063\x006F\x0067\x006E\x0069\x007A\x0065\x0064\x0020\x004E\x006F\x0064\x0065\x0020\x0054\x0079\x0070\x0065\x00"
-    24604             L"\x0050\x0061\x0072\x0073\x0065\x0020\x006D\x0061\x0079\x0020\x006E\x006F\x0074\x0020\x0062\x0065\x0020\x0063\x0061\x006C\x006C\x0065\x0064\x0020\x0077\x0068\x0069\x006C\x0065\x0020\x0070\x0061\x0072\x0073\x0069\x006E\x0067\x00"
-    24605             L"\x0050\x0061\x0072\x0073\x0069\x006E\x0067\x0020\x0068\x0061\x0073\x0020\x0062\x0065\x0065\x006E\x0020\x0061\x0062\x006F\x0072\x0074\x0065\x0064\x0020\x0062\x0079\x0020\x0074\x0068\x0065\x0020\x0075\x0073\x0065\x0072\x00"
+    24601             L"\x004A\x0075\x0073\x0074\x0020\x0061\x006E\x0020\x0069\x006E\x0064\x0065\x0078\x00"
+    24602             L"\x0054\x0068\x0065\x0020\x0065\x0078\x0070\x0072\x0065\x0073\x0073\x0069\x006F\x006E\x0020\x0068\x0061\x0073\x0020\x0061\x0020\x0073\x0079\x006E\x0074\x0061\x0078\x0020\x0065\x0072\x0072\x006F\x0072\x002C\x0020\x006F\x0072\x0020\x0063\x006F\x006E\x0074\x0061\x0069\x006E\x0073\x0020\x0058\x0050\x0061\x0074\x0068\x0020\x0066\x0065\x0061\x0074\x0075\x0072\x0065\x0073\x0020\x006E\x006F\x0074\x0020\x0073\x0075\x0070\x0070\x006F\x0072\x0074\x0065\x0064\x0020\x0062\x0079\x0020\x0074\x0068\x0065\x0020\x0058\x0050\x0061\x0074\x0068\x0020\x0066\x006F\x0072\x0020\x0058\x004D\x004C\x0053\x0063\x0068\x0065\x006D\x0061\x0020\x0073\x0079\x006E\x0074\x0061\x0078\x00"
+    24603             L"\x0054\x0068\x0065\x0020\x0072\x0065\x0071\x0075\x0065\x0073\x0074\x0065\x0064\x0020\x0072\x0065\x0073\x0075\x006C\x0074\x0020\x0074\x0079\x0070\x0065\x0020\x0069\x0073\x0020\x006E\x006F\x0074\x0020\x0073\x0075\x0070\x0070\x006F\x0072\x0074\x0065\x0064\x00"
+    24604             L"\x004E\x0065\x0073\x0074\x0065\x0064\x0020\x0043\x0044\x0041\x0054\x0041\x0020\x0073\x0065\x0063\x0074\x0069\x006F\x006E\x0073\x00"
+    24605             L"\x0055\x006E\x0072\x0065\x0070\x0072\x0065\x0073\x0065\x006E\x0074\x0061\x0062\x006C\x0065\x0020\x0063\x0068\x0061\x0072\x0061\x0063\x0074\x0065\x0072\x0020\x0064\x0061\x0074\x0061\x00"
+    24606             L"\x0055\x006E\x0072\x0065\x0063\x006F\x0067\x006E\x0069\x007A\x0065\x0064\x0020\x004E\x006F\x0064\x0065\x0020\x0054\x0079\x0070\x0065\x00"
+    24607             L"\x0050\x0061\x0072\x0073\x0065\x0020\x006D\x0061\x0079\x0020\x006E\x006F\x0074\x0020\x0062\x0065\x0020\x0063\x0061\x006C\x006C\x0065\x0064\x0020\x0077\x0068\x0069\x006C\x0065\x0020\x0070\x0061\x0072\x0073\x0069\x006E\x0067\x00"
+    24608             L"\x0050\x0061\x0072\x0073\x0069\x006E\x0067\x0020\x0068\x0061\x0073\x0020\x0062\x0065\x0065\x006E\x0020\x0061\x0062\x006F\x0072\x0074\x0065\x0064\x0020\x0062\x0079\x0020\x0074\x0068\x0065\x0020\x0075\x0073\x0065\x0072\x00"
 END
 
 #endif    // English (U.S.) resources
diff --git a/src/xercesc/util/XMLDOMMsg.hpp b/src/xercesc/util/XMLDOMMsg.hpp
index 753080023..d6622d4f2 100644
--- a/src/xercesc/util/XMLDOMMsg.hpp
+++ b/src/xercesc/util/XMLDOMMsg.hpp
@@ -39,16 +39,19 @@ public :
       , DOMLSEXCEPTION_ERRX                = 22
       , PARSE_ERR                          = 23
       , SERIALIZE_ERR                      = 24
-      , Writer_NestedCDATA                 = 25
-      , Writer_NotRepresentChar            = 26
-      , Writer_NotRecognizedType           = 27
-      , LSParser_ParseInProgress           = 28
-      , LSParser_ParsingAborted            = 29
-      , F_HighBounds                       = 30
-      , W_LowBounds                        = 31
-      , W_HighBounds                       = 32
-      , E_LowBounds                        = 33
-      , E_HighBounds                       = 34
+      , DOMXPATHEXCEPTION_ERRX             = 25
+      , INVALID_EXPRESSION_ERR             = 26
+      , TYPE_ERR                           = 27
+      , Writer_NestedCDATA                 = 28
+      , Writer_NotRepresentChar            = 29
+      , Writer_NotRecognizedType           = 30
+      , LSParser_ParseInProgress           = 31
+      , LSParser_ParsingAborted            = 32
+      , F_HighBounds                       = 33
+      , W_LowBounds                        = 34
+      , W_HighBounds                       = 35
+      , E_LowBounds                        = 36
+      , E_HighBounds                       = 37
     };
 
     static bool isFatal(const XMLDOMMsg::Codes toCheck)
diff --git a/src/xercesc/validators/schema/NamespaceScope.hpp b/src/xercesc/validators/schema/NamespaceScope.hpp
index 5e4d49edf..4ebf5ed22 100644
--- a/src/xercesc/validators/schema/NamespaceScope.hpp
+++ b/src/xercesc/validators/schema/NamespaceScope.hpp
@@ -26,13 +26,21 @@
 
 XERCES_CPP_NAMESPACE_BEGIN
 
+// Define a pure interface to allow XercesXPath to work on both NamespaceScope and DOMXPathNSResolver
+class VALIDATORS_EXPORT XercesNamespaceResolver
+{
+public:
+    virtual unsigned int getNamespaceForPrefix(const XMLCh* const prefix) = 0;
+};
+
 //
 // NamespaceScope provides a data structure for mapping namespace prefixes
 // to their URI's. The mapping accurately reflects the scoping of namespaces
 // at a particular instant in time.
 //
 
-class VALIDATORS_EXPORT NamespaceScope : public XMemory
+class VALIDATORS_EXPORT NamespaceScope : public XMemory,
+                                         public XercesNamespaceResolver
 {
 public :
     // -----------------------------------------------------------------------
@@ -83,9 +91,9 @@ public :
     void addPrefix(const XMLCh* const prefixToAdd,
                    const unsigned int uriId);
 
-    unsigned int getNamespaceForPrefix(const XMLCh* const prefixToMap) const;
-    unsigned int getNamespaceForPrefix(const XMLCh* const prefixToMap,
-                                       const int depthLevel) const;
+    unsigned int getNamespaceForPrefix(const XMLCh* const prefixToMap, const int depthLevel) const;
+
+    virtual unsigned int getNamespaceForPrefix(const XMLCh* const prefixToMap);
 
 
     // -----------------------------------------------------------------------
@@ -142,7 +150,7 @@ private :
 //  NamespaceScope: Stack access
 // ---------------------------------------------------------------------------
 inline unsigned int
-NamespaceScope::getNamespaceForPrefix(const XMLCh* const prefixToMap) const {
+NamespaceScope::getNamespaceForPrefix(const XMLCh* const prefixToMap) {
 
     return getNamespaceForPrefix(prefixToMap, (int)(fStackTop - 1));
 }
diff --git a/src/xercesc/validators/schema/identity/XPathMatcher.hpp b/src/xercesc/validators/schema/identity/XPathMatcher.hpp
index 3825e8de5..0e4c5cf08 100644
--- a/src/xercesc/validators/schema/identity/XPathMatcher.hpp
+++ b/src/xercesc/validators/schema/identity/XPathMatcher.hpp
@@ -83,8 +83,6 @@ public:
     virtual void endElement(const XMLElementDecl& elemDecl,
                             const XMLCh* const elemContent);
 
-protected:
-
     enum
     {
         XP_MATCHED = 1        // matched any way
@@ -94,6 +92,8 @@ protected:
                               // descendant-or-self-axis, but not this node
     };
 
+protected:
+
     // -----------------------------------------------------------------------
     //  Match methods
     // -----------------------------------------------------------------------
diff --git a/src/xercesc/validators/schema/identity/XercesXPath.cpp b/src/xercesc/validators/schema/identity/XercesXPath.cpp
index e1dc061cd..86d21cbf3 100644
--- a/src/xercesc/validators/schema/identity/XercesXPath.cpp
+++ b/src/xercesc/validators/schema/identity/XercesXPath.cpp
@@ -294,7 +294,7 @@ typedef JanitorMemFunCall<XercesXPath>  CleanupType;
 // ---------------------------------------------------------------------------
 XercesXPath::XercesXPath(const XMLCh* const xpathExpr,
                          XMLStringPool* const stringPool,
-                         NamespaceScope* const scopeContext,
+                         XercesNamespaceResolver* const scopeContext,
                          const unsigned int emptyNamespaceId,
                          const bool isSelector,
                          MemoryManager* const manager)
@@ -380,7 +380,7 @@ void XercesXPath::checkForSelectedAttributes() {
 }
 
 void XercesXPath::parseExpression(XMLStringPool* const stringPool,
-                                  NamespaceScope* const scopeContext) {
+                                  XercesNamespaceResolver* const scopeContext) {
 
     unsigned int length = XMLString::stringLen(fExpression);
 
diff --git a/src/xercesc/validators/schema/identity/XercesXPath.hpp b/src/xercesc/validators/schema/identity/XercesXPath.hpp
index 9658f488d..fac8bad18 100644
--- a/src/xercesc/validators/schema/identity/XercesXPath.hpp
+++ b/src/xercesc/validators/schema/identity/XercesXPath.hpp
@@ -29,7 +29,7 @@
 #include <xercesc/util/QName.hpp>
 #include <xercesc/util/RefVectorOf.hpp>
 #include <xercesc/util/ValueVectorOf.hpp>
-
+#include <xercesc/validators/schema/NamespaceScope.hpp>
 #include <xercesc/internal/XSerializable.hpp>
 
 XERCES_CPP_NAMESPACE_BEGIN
@@ -38,8 +38,6 @@ XERCES_CPP_NAMESPACE_BEGIN
 //  Forward Declarations
 // ---------------------------------------------------------------------------
 class XMLStringPool;
-class NamespaceScope;
-
 
 class VALIDATORS_EXPORT XercesNodeTest : public XSerializable, public XMemory
 {
@@ -262,7 +260,7 @@ public:
     // -----------------------------------------------------------------------
     XercesXPath(const XMLCh* const xpathExpr,
                 XMLStringPool* const stringPool,
-                NamespaceScope* const scopeContext,
+                XercesNamespaceResolver* const scopeContext,
                 const unsigned int emptyNamespaceId,
                 const bool isSelector = false,
                 MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
@@ -301,7 +299,7 @@ private:
     void cleanUp();
     void checkForSelectedAttributes();
     void parseExpression(XMLStringPool* const stringPool,
-                         NamespaceScope* const scopeContext);
+                         XercesNamespaceResolver* const scopeContext);
 
     // -----------------------------------------------------------------------
     //  Data members
diff --git a/tests/src/DOM/DOMTest/DTest.cpp b/tests/src/DOM/DOMTest/DTest.cpp
index 55cce99ca..7744a89f9 100644
--- a/tests/src/DOM/DOMTest/DTest.cpp
+++ b/tests/src/DOM/DOMTest/DTest.cpp
@@ -169,7 +169,7 @@ DOMNotation*                DOMTest::testNotationNode;
 
 DOMTest::DOMTest()
 {
-};
+}
 
 
 /**
@@ -183,7 +183,7 @@ DOMDocument* DOMTest::createDocument() {
 
     DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(coreStr);
     return impl->createDocument();
-};
+}
 
 
 /**
@@ -194,7 +194,7 @@ DOMDocument* DOMTest::createDocument() {
  */
 DOMDocumentType* DOMTest::createDocumentType(DOMDocument* doc, XMLCh* name) {
     return doc->createDocumentType(name);    //Replace with a DOMDocumentType* creator
-};
+}
 
 
 /**
@@ -206,7 +206,7 @@ DOMDocumentType* DOMTest::createDocumentType(DOMDocument* doc, XMLCh* name) {
  */
 DOMEntity* DOMTest::createEntity(DOMDocument* doc, XMLCh* name) {
     return doc->createEntity(name);
-};
+}
 
 
 
@@ -219,7 +219,7 @@ DOMEntity* DOMTest::createEntity(DOMDocument* doc, XMLCh* name) {
  */
 DOMNotation* DOMTest::createNotation(DOMDocument* doc, XMLCh* name) {
     return doc->createNotation(name);
-};
+}
 
 
 /**
@@ -702,7 +702,7 @@ bool DOMTest::docBuilder(DOMDocument* document, XMLCh* nameIn)
 
      // docBodyLevel32->getAttributes()->removeNamedItem(testAttribute->getName());    16  // To test removeNamedItem
 
-};  //END OF DOCBUILDER
+}  //END OF DOCBUILDER
 
 
 
@@ -760,7 +760,7 @@ void DOMTest::findTestNodes(DOMDocument* document) {
     }// End of switch
 
     }   // End of while
-};
+}
 
 
 /**
@@ -827,7 +827,7 @@ void DOMTest::findTestNodes(DOMNode* node) {
         default:
             ;
     }// End of switch
-};//End of class
+}//End of class
 
 /**
  *
@@ -896,6 +896,7 @@ int main(int /*argc*/, char ** /*argv*/)
          OK = test.testPI(d);
          OK = test.testText(d);
          OK = test.testDOMerrors(d);
+         OK = test.testXPath(d);
 
          // Null out the static object references in class DOMTest,
          // which will recover their storage.
@@ -956,7 +957,7 @@ int main(int /*argc*/, char ** /*argv*/)
     printf("Test Run Successfully\n");
 
     return 0;
-};
+}
 
 
 /**
@@ -1059,7 +1060,7 @@ bool DOMTest::testAttr(DOMDocument* document)
     if (node->getNodeValue() != 0 && attributeNode->getNodeValue() == 0)
     {
         cloneOK = false;
-    };
+    }
 
     if (node->getNodeValue() != 0 && attributeNode->getNodeValue() != 0)
     {
@@ -1460,7 +1461,7 @@ bool DOMTest::testAttr(DOMDocument* document)
         printf("\n*****The DOMAttr* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
 
-};
+}
 
 
 
@@ -1626,7 +1627,7 @@ bool DOMTest::testCDATASection(DOMDocument* document)
     if (! OK)
         printf("\n*****The DOMCDATASection* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -1892,7 +1893,7 @@ bool DOMTest::testCharacterData(DOMDocument* document)
         printf("\n*****The DOMCharacterData method calls listed above failed, all others worked correctly.*****\n");
     charData->setData(resetData); // reset node to original data
     return OK;
-};
+}
 
 
 
@@ -1920,7 +1921,7 @@ bool DOMTest::testChildNodeList(DOMDocument* document)
     if (!OK)
         printf("\n*****The ChildNodeList method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -2082,7 +2083,7 @@ bool DOMTest::testComment(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMComment* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -2127,7 +2128,7 @@ bool DOMTest::testDeepNodeList(DOMDocument* document)
     if (!OK)
         printf("\n*****The DeepNodeList method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -2419,7 +2420,7 @@ bool DOMTest::testDocument(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMDocument* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -2474,7 +2475,7 @@ bool DOMTest::testDocumentFragment(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMDocumentFragment* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -2652,7 +2653,7 @@ bool DOMTest::testDocumentType(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMDocumentType* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -2667,9 +2668,101 @@ bool DOMTest::testDOMerrors(DOMDocument* document) {
     EXCEPTIONSTEST(document->appendChild(testElementNode), DOMException::HIERARCHY_REQUEST_ERR, OK, 201 );
     EXCEPTIONSTEST(testTextNode->appendChild(testTextNode), DOMException::HIERARCHY_REQUEST_ERR, OK, 202 );
     return OK;
-};
+}
+
+#define TEST_VALID_XPATH(xpath, expected, line)   \
+    try \
+    { \
+        XMLCh xpathStr[100]; \
+        XMLString::transcode(xpath,xpathStr,99); \
+        DOMXPathResult* result=(DOMXPathResult*)document->evaluate(xpathStr, document->getDocumentElement(), NULL, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL); \
+        if(result->getSnapshotLength() != expected) {  \
+            fprintf(stderr, "DOMDocument::evaluate does not work in line %i (%d nodes instead of %d)\n", line, result->getSnapshotLength(), expected);  \
+            OK = false; \
+        }   \
+        result->release(); \
+    }   \
+    catch(DOMException&) \
+    {   \
+        fprintf(stderr, "DOMDocument::evaluate failed at line %i\n", line); \
+        OK = false; \
+    }
 
+#define TEST_VALID_XPATH_NS(xpath, resolver, expected, line)   \
+    try \
+    { \
+        XMLCh xpathStr[100]; \
+        XMLString::transcode(xpath,xpathStr,99); \
+        DOMXPathResult* result=(DOMXPathResult*)document->evaluate(xpathStr, document->getDocumentElement(), resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL); \
+        if(result->getSnapshotLength() != expected) {  \
+            fprintf(stderr, "DOMDocument::evaluate does not work in line %i (%d nodes instead of %d)\n", line, result->getSnapshotLength(), expected);  \
+            OK = false; \
+        }   \
+        result->release(); \
+    }   \
+    catch(DOMException&) \
+    {   \
+        fprintf(stderr, "DOMDocument::evaluate failed at line %i\n", line); \
+        OK = false; \
+    }
 
+#define TEST_INVALID_XPATH(xpath, line)   \
+    try \
+    { \
+        XMLCh xpathStr[100]; \
+        XMLString::transcode(xpath,xpathStr,99); \
+        DOMXPathResult* result=(DOMXPathResult*)document->evaluate(xpathStr, document->getDocumentElement(), NULL, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL); \
+        fprintf(stderr, "DOMDocument::evaluate does not work in line %i (invalid XPath)\n", line);  \
+        OK = false; \
+        result->release(); \
+    }   \
+    catch(DOMException& ) \
+    {   \
+    }
+
+#define TEST_VALID_XPATH_SINGLE(xpath, line)   \
+    try \
+    { \
+        XMLCh xpathStr[100]; \
+        XMLString::transcode(xpath,xpathStr,99); \
+        DOMXPathResult* result=(DOMXPathResult*)document->evaluate(xpathStr, document->getDocumentElement(), NULL, DOMXPathResult::FIRST_ORDERED_NODE_TYPE, NULL); \
+        if(result->getSingleNodeValue() == NULL) {  \
+            fprintf(stderr, "DOMDocument::evaluate does not work in line %i (single node not found)\n", line);  \
+            OK = false; \
+        }   \
+        result->release(); \
+    }   \
+    catch(DOMException& ) \
+    {   \
+        fprintf(stderr, "DOMDocument::evaluate failed at line %i\n", line); \
+        OK = false; \
+    }
+
+bool DOMTest::testXPath(DOMDocument* document) {
+    bool OK = true;
+
+    TEST_VALID_XPATH("*", 1, __LINE__);
+    TEST_VALID_XPATH("dFirstElement/dTestBody/dBodyLevel24", 1, __LINE__);
+    TEST_VALID_XPATH("//dBodyLevel34", 1, __LINE__);
+    TEST_VALID_XPATH("/*", 1, __LINE__);
+    TEST_VALID_XPATH("/dFirstElement/dTestBody/dBodyLevel24", 1, __LINE__);
+    TEST_INVALID_XPATH("/dFirstElement//dBodyLevel34", __LINE__);  // the "//" can only be at the beginning
+    TEST_INVALID_XPATH("/dFirstElement/@dFirstElementdFirstElement", __LINE__);   // cannot select attributes
+    TEST_VALID_XPATH("//*", 10, __LINE__);
+    TEST_VALID_XPATH_SINGLE("//*", __LINE__);
+    TEST_INVALID_XPATH("//ns:node", __LINE__);  // "ns" prefix is undefined
+
+    XMLCh tempStr[100];
+    XMLString::transcode("xmlns:ns",tempStr,99);
+    DOMAttr* attr=document->createAttributeNS(XMLUni::fgXMLNSURIName, tempStr);
+    attr->setNodeValue(XMLUni::fgXSAXMLScanner);
+    document->getDocumentElement()->setAttributeNodeNS(attr);
+    const DOMXPathNSResolver* resolver=document->createNSResolver(document->getDocumentElement());
+    TEST_VALID_XPATH_NS("//ns:node", resolver, 0, __LINE__);
+    document->getDocumentElement()->removeAttributeNode(attr);
+
+    return OK;
+}
 
 /**
  * This method tests DOMImplementation methods for the XML DOM implementation
@@ -2707,7 +2800,7 @@ bool DOMTest::testDOMImplementation(DOMDocument* document)
     if (!OK)
         fprintf(stderr, "\n*****The DOMImplementation method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -2800,7 +2893,7 @@ bool DOMTest::testElement(DOMDocument* document)
     {
         fprintf(stderr, "DOMElement* Tests Failure 001\n");
         OK = false;
-    };
+    }
     DOMNode* rem = element->setAttributeNode(newAttributeNode);
     if (rem)
         rem->release();
@@ -2809,7 +2902,7 @@ bool DOMTest::testElement(DOMDocument* document)
     {
         fprintf(stderr, "DOMElement* Tests Failure 002\n");
         OK = false;
-    };
+    }
 
     // Fetch the newly added attribute node back out of from the named node map,
     //  and check that we are returned the same node that we put in->
@@ -2820,7 +2913,7 @@ bool DOMTest::testElement(DOMDocument* document)
     {
         fprintf(stderr, "DOMElement* Tests Failure 003\n");
         OK = false;
-    };
+    }
 
     // Fetch the newly added attribute back out directly from the element itself.
     XMLString::transcode("AnotherFirstElementAttribute", tempStr, 3999);
@@ -2829,7 +2922,7 @@ bool DOMTest::testElement(DOMDocument* document)
     {
         fprintf(stderr, "DOMElement* Tests Failure 004\n");
         OK = false;
-    };
+    }
 
 
 
@@ -3395,7 +3488,7 @@ bool DOMTest::testElement(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMElement* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -3558,7 +3651,7 @@ bool DOMTest::testEntity(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMEntity* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 /**
@@ -3721,7 +3814,7 @@ bool DOMTest::testEntityReference(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMEntityReference* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -3896,7 +3989,7 @@ bool DOMTest::testNode(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMNode*  method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -4061,7 +4154,7 @@ bool DOMTest::testNotation(DOMDocument* document)
     if (!OK)
         printf("\n*****The DOMNotation* method calls listed above failed, all others worked correctly.*****\n");
     return OK;
-};
+}
 
 
 
@@ -4250,7 +4343,7 @@ bool DOMTest::testPI(DOMDocument* document)
         printf("\n*****The PI method calls listed above failed, all others worked correctly.*****\n");
 
     return OK;
-};
+}
 
 
 
@@ -4441,7 +4534,7 @@ bool DOMTest::testText(DOMDocument* document)
         printf("\n*****The DOMText* method calls listed above failed, all others worked correctly.*****\n");
 
     return OK;
-};
+}
 
 
 /**
@@ -4915,6 +5008,6 @@ bool DOMTest::treeCompare(DOMNode* node, DOMNode* node2)
         return false;
 
     return answer;
-};
+}
 
 
diff --git a/tests/src/DOM/DOMTest/DTest.h b/tests/src/DOM/DOMTest/DTest.h
index 3e985454e..fccefc874 100644
--- a/tests/src/DOM/DOMTest/DTest.h
+++ b/tests/src/DOM/DOMTest/DTest.h
@@ -87,6 +87,7 @@ bool testDocumentFragment(DOMDocument* document);
 
 bool testDocumentType(DOMDocument* document);
 bool testDOMerrors(DOMDocument* document);
+bool testXPath(DOMDocument* document);
 bool testDOMImplementation(DOMDocument* document);
 bool testElement(DOMDocument* document);
 bool testEntity(DOMDocument* document);
diff --git a/tests/src/XSTSHarness/XSTSHarnessHandlers.cpp b/tests/src/XSTSHarness/XSTSHarnessHandlers.cpp
index e4baa0f85..4aa8a9190 100644
--- a/tests/src/XSTSHarness/XSTSHarnessHandlers.cpp
+++ b/tests/src/XSTSHarness/XSTSHarnessHandlers.cpp
@@ -172,7 +172,7 @@ void XSTSHarnessHandlers::endElement(const XMLCh* const uri,
                 XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " skipped" << XERCES_STD_QUALIFIER endl;
                 return;
             }
-            bool success=true;
+            bool success=true, fatalFailure=false;
             try
             {
                 fErrorHandler.resetErrors();
@@ -181,6 +181,7 @@ void XSTSHarnessHandlers::endElement(const XMLCh* const uri,
             }
             catch (const OutOfMemoryException&)
             {
+                fatalFailure=true;
                 XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " ran out of memory" << XERCES_STD_QUALIFIER endl;
                 success=false;
             }
@@ -191,31 +192,42 @@ void XSTSHarnessHandlers::endElement(const XMLCh* const uri,
             }
             catch (...)
             {
+                fatalFailure=true;
                 XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " crashed" << XERCES_STD_QUALIFIER endl;
                 success=false;
             }
             fTests++;
-            if(success && !fErrorHandler.getSawErrors())
+            if(fatalFailure)
             {
-                if(fCurrentTest.fExpectedResult!=valid)
-                {
-                    // skip the rest of the group, as we had problems with the schema itself
-                    fCurrentTest.fSkipped=true;
-                    fFailures++;
-                    XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " succeeded but was expected to fail" << XERCES_STD_QUALIFIER endl;
-                    printFile(fCurrentTest.fXSDName);
-                }
+                // skip the rest of the group, as we had problems with the schema itself
+                fCurrentTest.fSkipped=true;
+                fFailures++;
+                printFile(fCurrentTest.fXSDName);
             }
             else
             {
-                if(fCurrentTest.fExpectedResult!=invalid)
+                if(success && !fErrorHandler.getSawErrors())
+                {
+                    if(fCurrentTest.fExpectedResult!=valid)
+                    {
+                        // skip the rest of the group, as we had problems with the schema itself
+                        fCurrentTest.fSkipped=true;
+                        fFailures++;
+                        XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " succeeded but was expected to fail" << XERCES_STD_QUALIFIER endl;
+                        printFile(fCurrentTest.fXSDName);
+                    }
+                }
+                else
                 {
-                    // skip the rest of the group, as we had problems with the schema itself
-                    fCurrentTest.fSkipped=true;
-                    fFailures++;
-                    XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " failed but was expected to pass" << XERCES_STD_QUALIFIER endl;
-                    XERCES_STD_QUALIFIER cout << "Reported error: " << StrX(fErrorHandler.getErrorText()) << XERCES_STD_QUALIFIER endl;
-                    printFile(fCurrentTest.fXSDName);
+                    if(fCurrentTest.fExpectedResult!=invalid)
+                    {
+                        // skip the rest of the group, as we had problems with the schema itself
+                        fCurrentTest.fSkipped=true;
+                        fFailures++;
+                        XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " failed but was expected to pass" << XERCES_STD_QUALIFIER endl;
+                        XERCES_STD_QUALIFIER cout << "Reported error: " << StrX(fErrorHandler.getErrorText()) << XERCES_STD_QUALIFIER endl;
+                        printFile(fCurrentTest.fXSDName);
+                    }
                 }
             }
         }
@@ -228,7 +240,7 @@ void XSTSHarnessHandlers::endElement(const XMLCh* const uri,
                 XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " skipped" << XERCES_STD_QUALIFIER endl;
                 return;
             }
-            bool success=true;
+            bool success=true, fatalFailure=false;
             try
             {
                 fErrorHandler.resetErrors();
@@ -236,6 +248,7 @@ void XSTSHarnessHandlers::endElement(const XMLCh* const uri,
             }
             catch (const OutOfMemoryException&)
             {
+                fatalFailure=true;
                 XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " ran out of memory" << XERCES_STD_QUALIFIER endl;
                 success=false;
             }
@@ -246,29 +259,39 @@ void XSTSHarnessHandlers::endElement(const XMLCh* const uri,
             }
             catch (...)
             {
+                fatalFailure=true;
                 XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " crashed" << XERCES_STD_QUALIFIER endl;
                 success=false;
             }
             fTests++;
-            if(success && !fErrorHandler.getSawErrors())
+            if(fatalFailure)
             {
-                if(fCurrentTest.fExpectedResult!=valid)
-                {
-                    fFailures++;
-                    XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " succeeded but was expected to fail" << XERCES_STD_QUALIFIER endl;
-                    printFile(fCurrentTest.fXSDName);
-                    printFile(fCurrentTest.fXMLName);
-                }
+                fFailures++;
+                printFile(fCurrentTest.fXSDName);
+                printFile(fCurrentTest.fXMLName);
             }
             else
             {
-                if(fCurrentTest.fExpectedResult!=invalid)
+                if(success && !fErrorHandler.getSawErrors())
+                {
+                    if(fCurrentTest.fExpectedResult!=valid)
+                    {
+                        fFailures++;
+                        XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " succeeded but was expected to fail" << XERCES_STD_QUALIFIER endl;
+                        printFile(fCurrentTest.fXSDName);
+                        printFile(fCurrentTest.fXMLName);
+                    }
+                }
+                else
                 {
-                    fFailures++;
-                    XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " failed but was expected to pass" << XERCES_STD_QUALIFIER endl;
-                    XERCES_STD_QUALIFIER cout << "Reported error: " << StrX(fErrorHandler.getErrorText()) << XERCES_STD_QUALIFIER endl;
-                    printFile(fCurrentTest.fXSDName);
-                    printFile(fCurrentTest.fXMLName);
+                    if(fCurrentTest.fExpectedResult!=invalid)
+                    {
+                        fFailures++;
+                        XERCES_STD_QUALIFIER cout << "Test " << StrX(fCurrentTest.fTestName) << " failed but was expected to pass" << XERCES_STD_QUALIFIER endl;
+                        XERCES_STD_QUALIFIER cout << "Reported error: " << StrX(fErrorHandler.getErrorText()) << XERCES_STD_QUALIFIER endl;
+                        printFile(fCurrentTest.fXSDName);
+                        printFile(fCurrentTest.fXMLName);
+                    }
                 }
             }
         }
-- 
GitLab