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