зеркало из https://github.com/mozilla/gecko-dev.git
bug 113611, XPath and XSLT contexts. fixes bugs 96410, 102293, 92106, 110266, 116534 and a bunch of other cases not filed. This mostly fixes namespaces and some really bad speed issues by fixing the time when namespaces are resolved, how default priorities are computed and how templates are matched.
HUGE PERFWIN :-) r=peterv, sr=jst
This commit is contained in:
Родитель
4492253e5a
Коммит
ea01481726
|
@ -88,19 +88,13 @@ LOBJS =../source/base/ArrayList.$(OBJ_SUFFIX) \
|
|||
../source/xml/dom/mozImpl/MozillaProcInstruction.$(OBJ_SUFFIX) \
|
||||
../source/xml/dom/mozImpl/MozillaText.$(OBJ_SUFFIX) \
|
||||
../source/xpath/AdditiveExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/AttributeExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/AttributeValueTemplate.$(OBJ_SUFFIX) \
|
||||
../source/xpath/BasicNodeExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/BooleanExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/BooleanFunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xpath/BooleanResult.$(OBJ_SUFFIX) \
|
||||
../source/xpath/ElementExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/ErrorFunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xpath/Expr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/ExprLexer.$(OBJ_SUFFIX) \
|
||||
../source/xpath/ExprLexerChars.$(OBJ_SUFFIX) \
|
||||
../source/xpath/ExprParser.$(OBJ_SUFFIX) \
|
||||
../source/xpath/ExtensionFunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xpath/FilterExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/FunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xpath/LocationStep.$(OBJ_SUFFIX) \
|
||||
|
@ -122,7 +116,10 @@ LOBJS =../source/base/ArrayList.$(OBJ_SUFFIX) \
|
|||
../source/xpath/StringExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/StringFunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xpath/StringResult.$(OBJ_SUFFIX) \
|
||||
../source/xpath/TextExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/txNameTest.$(OBJ_SUFFIX) \
|
||||
../source/xpath/txNodeTypeTest.$(OBJ_SUFFIX) \
|
||||
../source/xpath/txForwardContext.$(OBJ_SUFFIX) \
|
||||
../source/xpath/txNodeSetContext.$(OBJ_SUFFIX) \
|
||||
../source/xpath/UnionExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/UnaryExpr.$(OBJ_SUFFIX) \
|
||||
../source/xpath/VariableRefExpr.$(OBJ_SUFFIX) \
|
||||
|
@ -140,6 +137,8 @@ LOBJS =../source/base/ArrayList.$(OBJ_SUFFIX) \
|
|||
../source/xslt/txRtfHandler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txTextHandler.$(OBJ_SUFFIX) \
|
||||
../source/xslt/VariableBinding.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txXSLTPatterns.$(OBJ_SUFFIX) \
|
||||
../source/xslt/txPatternParser.$(OBJ_SUFFIX) \
|
||||
../source/xslt/XSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../source/xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
|
||||
../source/xslt/functions/DocumentFunctionCall.$(OBJ_SUFFIX) \
|
||||
|
|
|
@ -73,19 +73,13 @@ CPP_OBJS= \
|
|||
..\source\xml\dom\mozImpl\$(OBJDIR)\MozillaProcInstruction.obj \
|
||||
..\source\xml\dom\mozImpl\$(OBJDIR)\MozillaText.obj \
|
||||
..\source\xpath\$(OBJDIR)\AdditiveExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\AttributeExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\AttributeValueTemplate.obj \
|
||||
..\source\xpath\$(OBJDIR)\BasicNodeExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\BooleanExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\BooleanFunctionCall.obj \
|
||||
..\source\xpath\$(OBJDIR)\BooleanResult.obj \
|
||||
..\source\xpath\$(OBJDIR)\ElementExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\ErrorFunctionCall.obj \
|
||||
..\source\xpath\$(OBJDIR)\Expr.obj \
|
||||
..\source\xpath\$(OBJDIR)\ExprLexer.obj \
|
||||
..\source\xpath\$(OBJDIR)\ExprLexerChars.obj \
|
||||
..\source\xpath\$(OBJDIR)\ExprParser.obj \
|
||||
..\source\xpath\$(OBJDIR)\ExtensionFunctionCall.obj \
|
||||
..\source\xpath\$(OBJDIR)\FilterExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\FunctionCall.obj \
|
||||
..\source\xpath\$(OBJDIR)\LocationStep.obj \
|
||||
|
@ -107,7 +101,10 @@ CPP_OBJS= \
|
|||
..\source\xpath\$(OBJDIR)\StringExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\StringFunctionCall.obj \
|
||||
..\source\xpath\$(OBJDIR)\StringResult.obj \
|
||||
..\source\xpath\$(OBJDIR)\TextExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\txNameTest.obj \
|
||||
..\source\xpath\$(OBJDIR)\txNodeTypeTest.obj \
|
||||
..\source\xpath\$(OBJDIR)\txForwardContext.obj \
|
||||
..\source\xpath\$(OBJDIR)\txNodeSetContext.obj \
|
||||
..\source\xpath\$(OBJDIR)\UnionExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\UnaryExpr.obj \
|
||||
..\source\xpath\$(OBJDIR)\VariableRefExpr.obj \
|
||||
|
@ -125,6 +122,8 @@ CPP_OBJS= \
|
|||
..\source\xslt\$(OBJDIR)\txRtfHandler.obj \
|
||||
..\source\xslt\$(OBJDIR)\txTextHandler.obj \
|
||||
..\source\xslt\$(OBJDIR)\VariableBinding.obj \
|
||||
..\source\xslt\$(OBJDIR)\txXSLTPatterns.obj \
|
||||
..\source\xslt\$(OBJDIR)\txPatternParser.obj \
|
||||
..\source\xslt\$(OBJDIR)\XSLTProcessor.obj \
|
||||
..\source\xslt\functions\$(OBJDIR)\CurrentFunctionCall.obj \
|
||||
..\source\xslt\functions\$(OBJDIR)\DocumentFunctionCall.obj \
|
||||
|
|
|
@ -1009,6 +1009,34 @@
|
|||
<FILEKIND>Library</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNameTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeTypeTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txForwardContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeSetContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>MozillaNode.cpp</PATH>
|
||||
|
@ -1121,34 +1149,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>BasicNodeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>AttributeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ElementExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ErrorFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>FilterExpr.cpp</PATH>
|
||||
|
@ -1436,13 +1436,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>TextExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ArrayList.cpp</PATH>
|
||||
|
@ -1478,13 +1471,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExtensionFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>GenerateIdFunctionCall.cpp</PATH>
|
||||
|
@ -1569,13 +1555,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Expr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexerChars.cpp</PATH>
|
||||
|
@ -1702,6 +1681,20 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txPatternParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTPatterns.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
</FILELIST>
|
||||
<LINKORDER>
|
||||
<FILEREF>
|
||||
|
@ -1739,6 +1732,26 @@
|
|||
<PATH>UnicharUtilsStaticDebug.o</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNameTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeTypeTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txForwardContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeSetContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>List.cpp</PATH>
|
||||
|
@ -1799,26 +1812,6 @@
|
|||
<PATH>VariableBinding.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>BasicNodeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>AttributeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ElementExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ErrorFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>FilterExpr.cpp</PATH>
|
||||
|
@ -1959,11 +1952,6 @@
|
|||
<PATH>RootExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>TextExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ArrayList.cpp</PATH>
|
||||
|
@ -2074,11 +2062,6 @@
|
|||
<PATH>XMLParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExtensionFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>GenerateIdFunctionCall.cpp</PATH>
|
||||
|
@ -2139,11 +2122,6 @@
|
|||
<PATH>txKeyFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Expr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexerChars.cpp</PATH>
|
||||
|
@ -2229,6 +2207,16 @@
|
|||
<PATH>txExpandedNameMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txPatternParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTPatterns.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
</LINKORDER>
|
||||
</TARGET>
|
||||
<TARGET>
|
||||
|
@ -3271,34 +3259,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>BasicNodeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>AttributeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ElementExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ErrorFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>FilterExpr.cpp</PATH>
|
||||
|
@ -3586,13 +3546,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>TextExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ArrayList.cpp</PATH>
|
||||
|
@ -3656,13 +3609,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExtensionFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>GenerateIdFunctionCall.cpp</PATH>
|
||||
|
@ -3747,13 +3693,6 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Expr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS></FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexerChars.cpp</PATH>
|
||||
|
@ -3880,6 +3819,48 @@
|
|||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txForwardContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNameTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeSetContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeTypeTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txPatternParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
<FILE>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTPatterns.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
<FILEKIND>Text</FILEKIND>
|
||||
<FILEFLAGS>Debug</FILEFLAGS>
|
||||
</FILE>
|
||||
</FILELIST>
|
||||
<LINKORDER>
|
||||
<FILEREF>
|
||||
|
@ -3957,26 +3938,6 @@
|
|||
<PATH>VariableBinding.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>BasicNodeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>AttributeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ElementExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ErrorFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>FilterExpr.cpp</PATH>
|
||||
|
@ -4117,11 +4078,6 @@
|
|||
<PATH>RootExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>TextExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ArrayList.cpp</PATH>
|
||||
|
@ -4252,11 +4208,6 @@
|
|||
<PATH>XMLParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExtensionFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>GenerateIdFunctionCall.cpp</PATH>
|
||||
|
@ -4317,11 +4268,6 @@
|
|||
<PATH>txKeyFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Expr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExprLexerChars.cpp</PATH>
|
||||
|
@ -4407,6 +4353,36 @@
|
|||
<PATH>txExpandedNameMap.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txForwardContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNameTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeSetContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeTypeTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txPatternParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTPatterns.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
</LINKORDER>
|
||||
</TARGET>
|
||||
</TARGETLIST>
|
||||
|
@ -4645,24 +4621,12 @@
|
|||
<PATH>AdditiveExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>AttributeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>AttributeValueTemplate.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>BasicNodeExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
|
@ -4681,24 +4645,6 @@
|
|||
<PATH>BooleanResult.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ElementExpr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ErrorFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>Expr.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
|
@ -4717,12 +4663,6 @@
|
|||
<PATH>ExprParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>ExtensionFunctionCall.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
|
@ -4852,7 +4792,25 @@
|
|||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>TextExpr.cpp</PATH>
|
||||
<PATH>txForwardContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNameTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeSetContext.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txNodeTypeTest.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
|
@ -4917,6 +4875,12 @@
|
|||
<PATH>txOutputFormat.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txPatternParser.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
|
@ -4929,6 +4893,12 @@
|
|||
<PATH>txTextHandler.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
<PATH>txXSLTPatterns.cpp</PATH>
|
||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||
</FILEREF>
|
||||
<FILEREF>
|
||||
<TARGETNAME>transformiixDebug.shlb</TARGETNAME>
|
||||
<PATHTYPE>Name</PATHTYPE>
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "baseutils.h"
|
||||
#include "TxString.h"
|
||||
#include "txError.h"
|
||||
#include <iostream.h>
|
||||
|
||||
/**
|
||||
|
@ -37,23 +38,26 @@ class ErrorObserver {
|
|||
|
||||
public:
|
||||
|
||||
enum ErrorLevel {FATAL = 0, NORMAL, WARNING};
|
||||
|
||||
/**
|
||||
* Default Destructor for ErrorObserver
|
||||
**/
|
||||
virtual ~ErrorObserver() {};
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error, with default
|
||||
* level of NORMAL
|
||||
* Notifies this Error observer of a new error aRes
|
||||
**/
|
||||
virtual void recieveError(String& errorMessage) = 0;
|
||||
virtual void receiveError(const String& errorMessage, nsresult aRes) = 0;
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error using the given error level
|
||||
* Notifies this Error observer of a new error, with default
|
||||
* error code NS_ERROR_FAILURE
|
||||
**/
|
||||
virtual void recieveError(String& errorMessage, ErrorLevel level) = 0;
|
||||
void receiveError(String& errorMessage)
|
||||
{
|
||||
receiveError(errorMessage, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}; //-- ErrorObserver
|
||||
|
||||
|
@ -79,15 +83,9 @@ public:
|
|||
virtual ~SimpleErrorObserver() {};
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error, with default
|
||||
* level of NORMAL
|
||||
* Notifies this Error observer of a new error aRes
|
||||
**/
|
||||
virtual void recieveError(String& errorMessage);
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error using the given error level
|
||||
**/
|
||||
virtual void recieveError(String& errorMessage, ErrorLevel level);
|
||||
void receiveError(const String& errorMessage, nsresult aRes);
|
||||
|
||||
virtual void supressWarnings(MBool supress);
|
||||
|
||||
|
|
|
@ -45,39 +45,21 @@ SimpleErrorObserver::SimpleErrorObserver(ostream& errStream) {
|
|||
hideWarnings = MB_FALSE;
|
||||
} //-- SimpleErrorObserver
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error, with default
|
||||
* level of NORMAL
|
||||
**/
|
||||
void SimpleErrorObserver::recieveError(String& errorMessage) {
|
||||
#ifdef TX_EXE
|
||||
*errStream << "error: " << errorMessage << endl;
|
||||
errStream->flush();
|
||||
#endif
|
||||
} //-- recieveError
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error using the given error level
|
||||
**/
|
||||
void SimpleErrorObserver::recieveError(String& errorMessage, ErrorLevel level) {
|
||||
void SimpleErrorObserver::receiveError(const String& errorMessage,
|
||||
nsresult aRes)
|
||||
{
|
||||
#ifdef TX_EXE
|
||||
switch ( level ) {
|
||||
case ErrorObserver::FATAL :
|
||||
*errStream << "fatal error: ";
|
||||
break;
|
||||
case ErrorObserver::WARNING :
|
||||
if ( hideWarnings ) return;
|
||||
*errStream << "warning: ";
|
||||
break;
|
||||
default:
|
||||
*errStream << "error: ";
|
||||
break;
|
||||
if (NS_FAILED(aRes)) {
|
||||
*errStream << "error: ";
|
||||
}
|
||||
|
||||
*errStream << errorMessage << endl;
|
||||
errStream->flush();
|
||||
#endif
|
||||
} //-- recieveError
|
||||
}
|
||||
|
||||
void SimpleErrorObserver::supressWarnings(MBool supress) {
|
||||
this->hideWarnings = supress;
|
||||
|
|
|
@ -68,4 +68,9 @@ typedef PRUint32 nsresult;
|
|||
|
||||
#endif // TX_EXE
|
||||
|
||||
#define NS_ERROR_XPATH_EVAL_FAILED NS_ERROR_FAILURE
|
||||
#define NS_ERROR_XPATH_PARSE_FAILED NS_ERROR_FAILURE
|
||||
#define NS_ERROR_XPATH_INVALID_ARG NS_ERROR_INVALID_ARG
|
||||
#define NS_ERROR_XSLT_INVALID_URL NS_ERROR_INVALID_ARG
|
||||
|
||||
#endif // __TX_ERROR
|
||||
|
|
|
@ -61,19 +61,13 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
|
|||
../xml/dom/standalone/ProcessingInstruction.$(OBJ_SUFFIX) \
|
||||
../xml/dom/standalone/Text.$(OBJ_SUFFIX) \
|
||||
../xpath/AdditiveExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/AttributeExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/AttributeValueTemplate.$(OBJ_SUFFIX) \
|
||||
../xpath/BasicNodeExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/BooleanExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/BooleanFunctionCall.$(OBJ_SUFFIX) \
|
||||
../xpath/BooleanResult.$(OBJ_SUFFIX) \
|
||||
../xpath/ElementExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/ErrorFunctionCall.$(OBJ_SUFFIX) \
|
||||
../xpath/Expr.$(OBJ_SUFFIX) \
|
||||
../xpath/ExprLexer.$(OBJ_SUFFIX) \
|
||||
../xpath/ExprLexerChars.$(OBJ_SUFFIX) \
|
||||
../xpath/ExprParser.$(OBJ_SUFFIX) \
|
||||
../xpath/ExtensionFunctionCall.$(OBJ_SUFFIX) \
|
||||
../xpath/FilterExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/FunctionCall.$(OBJ_SUFFIX) \
|
||||
../xpath/LocationStep.$(OBJ_SUFFIX) \
|
||||
|
@ -90,7 +84,10 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
|
|||
../xpath/StringExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/StringFunctionCall.$(OBJ_SUFFIX) \
|
||||
../xpath/StringResult.$(OBJ_SUFFIX) \
|
||||
../xpath/TextExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/txNameTest.$(OBJ_SUFFIX) \
|
||||
../xpath/txNodeTypeTest.$(OBJ_SUFFIX) \
|
||||
../xpath/txForwardContext.$(OBJ_SUFFIX) \
|
||||
../xpath/txNodeSetContext.$(OBJ_SUFFIX) \
|
||||
../xpath/UnionExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/UnaryExpr.$(OBJ_SUFFIX) \
|
||||
../xpath/VariableRefExpr.$(OBJ_SUFFIX) \
|
||||
|
@ -111,6 +108,8 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
|
|||
../xslt/txTextHandler.$(OBJ_SUFFIX) \
|
||||
../xslt/txTextOutput.$(OBJ_SUFFIX) \
|
||||
../xslt/txXMLOutput.$(OBJ_SUFFIX) \
|
||||
../xslt/txXSLTPatterns.$(OBJ_SUFFIX) \
|
||||
../xslt/txPatternParser.$(OBJ_SUFFIX) \
|
||||
../xslt/VariableBinding.$(OBJ_SUFFIX) \
|
||||
../xslt/XSLTProcessor.$(OBJ_SUFFIX) \
|
||||
../xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
|
||||
|
|
|
@ -59,19 +59,13 @@ CPP_OBJS= \
|
|||
../xml/dom/standalone/$(OBJDIR)/ProcessingInstruction.obj \
|
||||
../xml/dom/standalone/$(OBJDIR)/Text.obj \
|
||||
../xpath/$(OBJDIR)/AdditiveExpr.obj \
|
||||
../xpath/$(OBJDIR)/AttributeExpr.obj \
|
||||
../xpath/$(OBJDIR)/AttributeValueTemplate.obj \
|
||||
../xpath/$(OBJDIR)/BasicNodeExpr.obj \
|
||||
../xpath/$(OBJDIR)/BooleanExpr.obj \
|
||||
../xpath/$(OBJDIR)/BooleanFunctionCall.obj \
|
||||
../xpath/$(OBJDIR)/BooleanResult.obj \
|
||||
../xpath/$(OBJDIR)/ElementExpr.obj \
|
||||
../xpath/$(OBJDIR)/ErrorFunctionCall.obj \
|
||||
../xpath/$(OBJDIR)/Expr.obj \
|
||||
../xpath/$(OBJDIR)/ExprLexer.obj \
|
||||
../xpath/$(OBJDIR)/ExprLexerChars.obj \
|
||||
../xpath/$(OBJDIR)/ExprParser.obj \
|
||||
../xpath/$(OBJDIR)/ExtensionFunctionCall.obj \
|
||||
../xpath/$(OBJDIR)/FilterExpr.obj \
|
||||
../xpath/$(OBJDIR)/FunctionCall.obj \
|
||||
../xpath/$(OBJDIR)/LocationStep.obj \
|
||||
|
@ -88,7 +82,10 @@ CPP_OBJS= \
|
|||
../xpath/$(OBJDIR)/StringExpr.obj \
|
||||
../xpath/$(OBJDIR)/StringFunctionCall.obj \
|
||||
../xpath/$(OBJDIR)/StringResult.obj \
|
||||
../xpath/$(OBJDIR)/TextExpr.obj \
|
||||
../xpath/$(OBJDIR)/txNameTest.obj \
|
||||
../xpath/$(OBJDIR)/txNodeTypeTest.obj \
|
||||
../xpath/$(OBJDIR)/txForwardContext.obj \
|
||||
../xpath/$(OBJDIR)/txNodeSetContext.obj \
|
||||
../xpath/$(OBJDIR)/UnionExpr.obj \
|
||||
../xpath/$(OBJDIR)/UnaryExpr.obj \
|
||||
../xpath/$(OBJDIR)/VariableRefExpr.obj \
|
||||
|
@ -105,6 +102,8 @@ CPP_OBJS= \
|
|||
../xslt/$(OBJDIR)/txTextHandler.obj \
|
||||
../xslt/$(OBJDIR)/txTextOutput.obj \
|
||||
../xslt/$(OBJDIR)/txXMLOutput.obj \
|
||||
../xslt/$(OBJDIR)/txXSLTPatterns.obj \
|
||||
../xslt/$(OBJDIR)/txPatternParser.obj \
|
||||
../xslt/$(OBJDIR)/VariableBinding.obj \
|
||||
../xslt/$(OBJDIR)/XSLTProcessor.obj \
|
||||
../xslt/functions/$(OBJDIR)/CurrentFunctionCall.obj \
|
||||
|
|
|
@ -53,21 +53,20 @@ AdditiveExpr::~AdditiveExpr() {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* AdditiveExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
|
||||
ExprResult* AdditiveExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
double rightDbl = Double::NaN;
|
||||
ExprResult* exprRes = 0;
|
||||
|
||||
if ( rightExpr ) {
|
||||
exprRes = rightExpr->evaluate(context, cs);
|
||||
exprRes = rightExpr->evaluate(aContext);
|
||||
if ( exprRes ) rightDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
double leftDbl = Double::NaN;
|
||||
if ( leftExpr ) {
|
||||
exprRes = leftExpr->evaluate(context, cs);
|
||||
exprRes = leftExpr->evaluate(aContext);
|
||||
if ( exprRes ) leftDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
|
|
@ -1,153 +0,0 @@
|
|||
/*-*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
|
||||
/*
|
||||
This class represents a Attribute Expression as defined by the XPath
|
||||
1.0 Recommendation
|
||||
*/
|
||||
|
||||
const String AttributeExpr::WILD_CARD = "*";
|
||||
|
||||
//- Constructors -/
|
||||
|
||||
AttributeExpr::AttributeExpr(String& name)
|
||||
{
|
||||
if (name.isEqual(WILD_CARD)) {
|
||||
isNameWild = MB_TRUE;
|
||||
isNamespaceWild = MB_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = name.indexOf(':');
|
||||
if (idx >= 0)
|
||||
name.subString(0, idx, prefix);
|
||||
else
|
||||
idx = -1;
|
||||
|
||||
name.subString(idx+1, this->name);
|
||||
|
||||
//-- set flags
|
||||
isNamespaceWild = MB_FALSE;
|
||||
isNameWild = this->name.isEqual(WILD_CARD);
|
||||
} //-- AttributeExpr
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* AttributeExpr::evaluate(Node* context, ContextState* cs) {
|
||||
NS_ASSERTION(0, "AttributeExpr::evaluate called");
|
||||
return 0;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double AttributeExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
if (!isNameWild)
|
||||
return 0;
|
||||
if (!isNamespaceWild)
|
||||
return -0.25;
|
||||
return -0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
//-----------------------------/
|
||||
//- Methods from NodeExpr.cpp -/
|
||||
//-----------------------------/
|
||||
|
||||
/**
|
||||
* Determines whether this NodeExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool AttributeExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
//XXX need to filter out namespace-declaration attributes!
|
||||
|
||||
if ( (!node) || (node->getNodeType() != Node::ATTRIBUTE_NODE) )
|
||||
return MB_FALSE;
|
||||
|
||||
if ( isNameWild && isNamespaceWild ) return MB_TRUE;
|
||||
|
||||
const String nodeName = ((Attr*)node)->getName();
|
||||
int idx = nodeName.indexOf(':');
|
||||
if (idx >= 0) {
|
||||
String prefixForNode;
|
||||
nodeName.subString(0,idx,prefixForNode);
|
||||
String localName;
|
||||
nodeName.subString(idx+1, localName);
|
||||
if (isNamespaceWild) return localName.isEqual(this->name);
|
||||
String nsForNode;
|
||||
Node* parent = node->getXPathParent();
|
||||
if (parent)
|
||||
XMLDOMUtils::getNamespaceURI(prefixForNode, (Element*)parent,
|
||||
nsForNode);
|
||||
String nsForTest;
|
||||
if (!prefix.isEmpty())
|
||||
cs->getNameSpaceURIFromPrefix(prefix, nsForTest);
|
||||
if (!nsForTest.isEqual(nsForNode)) return MB_FALSE;
|
||||
return localName.isEqual(this->name);
|
||||
}
|
||||
else {
|
||||
if (isNamespaceWild) return nodeName.isEqual(this->name);
|
||||
String nsForTest;
|
||||
if (!prefix.isEmpty())
|
||||
cs->getNameSpaceURIFromPrefix(prefix, nsForTest);
|
||||
if (!nsForTest.isEmpty())
|
||||
return MB_FALSE;
|
||||
return nodeName.isEqual(this->name);
|
||||
}
|
||||
return MB_FALSE;
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this NodeExpr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this NodeExpr.
|
||||
**/
|
||||
void AttributeExpr::toString(String& dest) {
|
||||
if (isNameWild && isNamespaceWild) dest.append('*');
|
||||
else {
|
||||
dest.append(this->prefix);
|
||||
dest.append(':');
|
||||
dest.append(this->name);
|
||||
}
|
||||
} //-- toString
|
||||
|
|
@ -62,12 +62,13 @@ void AttributeValueTemplate::addExpr(Expr* expr) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* AttributeValueTemplate::evaluate(Node* context, ContextState* cs) {
|
||||
ExprResult* AttributeValueTemplate::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ListIterator* iter = expressions.iterator();
|
||||
String result;
|
||||
while ( iter->hasNext() ) {
|
||||
Expr* expr = (Expr*)iter->next();
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
ExprResult* exprResult = expr->evaluate(aContext);
|
||||
exprResult->stringValue(result);
|
||||
delete exprResult;
|
||||
}
|
||||
|
|
|
@ -1,124 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
//- Constructors -/
|
||||
|
||||
/**
|
||||
* Creates a new BasicNodeExpr of the given type
|
||||
**/
|
||||
BasicNodeExpr::BasicNodeExpr(NodeExpr::NodeExprType nodeExprType) {
|
||||
this->type = nodeExprType;
|
||||
nodeNameSet = MB_FALSE;
|
||||
} //-- BasicNodeExpr
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
void BasicNodeExpr::setNodeName(const String& name) {
|
||||
this->nodeName = name;
|
||||
nodeNameSet = MB_TRUE;
|
||||
}
|
||||
|
||||
//-----------------------------/
|
||||
//- Methods from NodeExpr.cpp -/
|
||||
//-----------------------------/
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* BasicNodeExpr::evaluate(Node* context, ContextState* cs) {
|
||||
NS_ASSERTION(0, "BasicNodeExpr::evaluate called");
|
||||
return 0;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Expr based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double BasicNodeExpr::getDefaultPriority(Node* node, Node* context,
|
||||
ContextState* cs) {
|
||||
if (nodeNameSet)
|
||||
return 0;
|
||||
return -0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this NodeExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool BasicNodeExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
if (!node)
|
||||
return MB_FALSE;
|
||||
switch (type) {
|
||||
case NodeExpr::COMMENT_EXPR:
|
||||
return (MBool)(node->getNodeType() == Node::COMMENT_NODE);
|
||||
case NodeExpr::PI_EXPR :
|
||||
return (MBool)(node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE &&
|
||||
!nodeNameSet || nodeName.isEqual(node->getNodeName()));
|
||||
default: //-- node()
|
||||
if (node->getNodeType() == Node::TEXT_NODE ||
|
||||
node->getNodeType() == Node::CDATA_SECTION_NODE)
|
||||
return !cs->isStripSpaceAllowed(node);
|
||||
return MB_TRUE;
|
||||
}
|
||||
return MB_TRUE;
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this NodeExpr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this NodeExpr.
|
||||
**/
|
||||
void BasicNodeExpr::toString(String& dest) {
|
||||
switch (type) {
|
||||
case NodeExpr::COMMENT_EXPR:
|
||||
dest.append("comment()");
|
||||
break;
|
||||
case NodeExpr::PI_EXPR :
|
||||
dest.append("processing-instruction(");
|
||||
if (nodeNameSet) {
|
||||
dest.append('\'');
|
||||
dest.append(nodeName);
|
||||
dest.append('\'');
|
||||
}
|
||||
dest.append(')');
|
||||
break;
|
||||
default: //-- node()
|
||||
dest.append("node()");
|
||||
break;
|
||||
}
|
||||
} //-- toString
|
||||
|
|
@ -57,13 +57,12 @@ BooleanExpr::~BooleanExpr() {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* BooleanExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
|
||||
ExprResult* BooleanExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
MBool lval = MB_FALSE;
|
||||
ExprResult* exprRes = 0;
|
||||
if ( leftExpr ) {
|
||||
exprRes = leftExpr->evaluate(context, cs);
|
||||
exprRes = leftExpr->evaluate(aContext);
|
||||
if ( exprRes ) lval = exprRes->booleanValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
@ -75,7 +74,7 @@ ExprResult* BooleanExpr::evaluate(Node* context, ContextState* cs) {
|
|||
|
||||
MBool rval = MB_FALSE;
|
||||
if ( rightExpr ) {
|
||||
exprRes = rightExpr->evaluate(context, cs);
|
||||
exprRes = rightExpr->evaluate(aContext);
|
||||
if ( exprRes ) rval = exprRes->booleanValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "FunctionLib.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/**
|
||||
* Creates a default BooleanFunctionCall, which always evaluates to False
|
||||
|
@ -62,27 +63,26 @@ BooleanFunctionCall::BooleanFunctionCall(BooleanFunctions aType)
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||
ExprResult* BooleanFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ListIterator iter(¶ms);
|
||||
|
||||
switch (mType) {
|
||||
case TX_BOOLEAN:
|
||||
{
|
||||
if (!requireParams(1, 1, aCs))
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
return new BooleanResult(evaluateToBoolean((Expr*)iter.next(),
|
||||
aContext,
|
||||
aCs));
|
||||
aContext));
|
||||
}
|
||||
case TX_LANG:
|
||||
{
|
||||
if (!requireParams(1, 1, aCs))
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String lang;
|
||||
Node* node = aContext;
|
||||
Node* node = aContext->getContextNode();
|
||||
while (node) {
|
||||
if (node->getNodeType() == Node::ELEMENT_NODE) {
|
||||
Element* elem = (Element*)node;
|
||||
|
@ -96,7 +96,7 @@ ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
MBool result = MB_FALSE;
|
||||
if (node) {
|
||||
String arg;
|
||||
evaluateToString((Expr*)iter.next(),aContext, aCs, arg);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg);
|
||||
arg.toUpperCase(); // case-insensitive comparison
|
||||
lang.toUpperCase();
|
||||
result = lang.indexOf(arg) == 0 &&
|
||||
|
@ -108,23 +108,22 @@ ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case TX_NOT:
|
||||
{
|
||||
if (!requireParams(1, 1, aCs))
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
return new BooleanResult(!evaluateToBoolean((Expr*)iter.next(),
|
||||
aContext,
|
||||
aCs));
|
||||
aContext));
|
||||
}
|
||||
case TX_TRUE:
|
||||
{
|
||||
if (!requireParams(0, 0, aCs))
|
||||
if (!requireParams(0, 0, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
return new BooleanResult(MB_TRUE);
|
||||
}
|
||||
case TX_FALSE:
|
||||
{
|
||||
if (!requireParams(0, 0, aCs))
|
||||
if (!requireParams(0, 0, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
return new BooleanResult(MB_FALSE);
|
||||
|
@ -132,7 +131,7 @@ ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,139 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
|
||||
/*
|
||||
This class represents a ElementExpr as defined by XPath 1.0
|
||||
proposed recommendation
|
||||
*/
|
||||
|
||||
|
||||
const String ElementExpr::WILD_CARD = "*";
|
||||
|
||||
|
||||
//- Constructors -/
|
||||
ElementExpr::ElementExpr(String& name)
|
||||
{
|
||||
int idx = name.indexOf(':');
|
||||
if (idx >= 0)
|
||||
name.subString(0, idx, prefix);
|
||||
else
|
||||
idx = -1;
|
||||
|
||||
name.subString(idx+1, this->name);
|
||||
|
||||
//-- set flags
|
||||
isNameWild = this->name.isEqual(WILD_CARD);
|
||||
isNamespaceWild = (isNameWild && prefix.isEmpty());
|
||||
} //-- ElementExpr
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* ElementExpr::evaluate(Node* context, ContextState* cs) {
|
||||
NS_ASSERTION(0, "ElementExpr::evaluate called");
|
||||
return 0;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double ElementExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
if (!isNameWild)
|
||||
return 0;
|
||||
if (!isNamespaceWild)
|
||||
return -0.25;
|
||||
return -0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
//-----------------------------/
|
||||
//- Methods from NodeExpr.cpp -/
|
||||
//-----------------------------/
|
||||
|
||||
/**
|
||||
* Determines whether this NodeExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool ElementExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
if ((!node) || (node->getNodeType() != Node::ELEMENT_NODE ))
|
||||
return MB_FALSE;
|
||||
|
||||
if (isNamespaceWild && isNameWild) return MB_TRUE;
|
||||
|
||||
const String nodeName = node->getNodeName();
|
||||
|
||||
int idx = nodeName.indexOf(':');
|
||||
|
||||
if (!isNamespaceWild) {
|
||||
//-- compare namespaces
|
||||
String nsURI;
|
||||
// use context to get namespace for testing against
|
||||
if (!prefix.isEmpty())
|
||||
cs->getNameSpaceURIFromPrefix(prefix, nsURI);
|
||||
|
||||
String nsURI2;
|
||||
String prefix2;
|
||||
if (idx > 0) nodeName.subString(0, idx, prefix2);
|
||||
// use source tree to aquire namespace for node
|
||||
XMLDOMUtils::getNamespaceURI(prefix2, (Element*) node, nsURI2);
|
||||
|
||||
if (!nsURI.isEqual(nsURI2)) return MB_FALSE;
|
||||
}
|
||||
|
||||
if (this->isNameWild) return MB_TRUE;
|
||||
//-- compare local names
|
||||
if (idx < 0) return nodeName.isEqual(this->name);
|
||||
else {
|
||||
String local;
|
||||
nodeName.subString(idx+1, local);
|
||||
return local.isEqual(this->name);
|
||||
}
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this NodeExpr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this NodeExpr.
|
||||
**/
|
||||
void ElementExpr::toString(String& dest) {
|
||||
dest.append(this->name);
|
||||
} //-- toString
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
|
||||
/**
|
||||
* Creates an Error FunctionCall with no error message
|
||||
**/
|
||||
ErrorFunctionCall::ErrorFunctionCall() : FunctionCall(XPathNames::ERROR_FN) {};
|
||||
|
||||
/**
|
||||
* Creates an Error FunctionCall with the given error message
|
||||
**/
|
||||
ErrorFunctionCall::ErrorFunctionCall
|
||||
(const String& errorMsg) : FunctionCall(XPathNames::ERROR_FN)
|
||||
{
|
||||
//-- copy errorMsg
|
||||
this->errorMessage = errorMsg;
|
||||
} //-- ErrorFunctionCall
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* ErrorFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
return new StringResult( errorMessage);
|
||||
} //-- evaluate
|
||||
|
||||
void ErrorFunctionCall::setErrorMessage(String& errorMsg) {
|
||||
//-- copy errorMsg
|
||||
this->errorMessage = errorMsg;
|
||||
} //-- setError
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Jonas Sicking.
|
||||
* Portions created by Jonas Sicking are Copyright (C) 2001, Jonas Sicking.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking, sicking@bigfoot.com
|
||||
* -- original author.
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
Expr::~Expr() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context.
|
||||
*/
|
||||
MBool Expr::matches(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
NS_ASSERTION(0, "Expr::matches() called");
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default priority of this Expr based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
*/
|
||||
double Expr::getDefaultPriority(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
NS_ASSERTION(0, "Expr::matches() called");
|
||||
return 0;
|
||||
}
|
|
@ -35,7 +35,7 @@
|
|||
#ifndef TRANSFRMX_EXPR_H
|
||||
#define TRANSFRMX_EXPR_H
|
||||
|
||||
|
||||
#include "txError.h"
|
||||
#include "TxString.h"
|
||||
#include "ErrorObserver.h"
|
||||
#include "NodeSet.h"
|
||||
|
@ -50,51 +50,12 @@
|
|||
Much of this code was ported from XSL:P.
|
||||
*/
|
||||
|
||||
//necessary prototypes
|
||||
class FunctionCall;
|
||||
|
||||
typedef class Expr Pattern;
|
||||
typedef class Expr PatternExpr;
|
||||
|
||||
|
||||
/**
|
||||
* The expression context and state class used when evaluating XPath Expressions.
|
||||
**/
|
||||
class ContextState : public ErrorObserver {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Returns the value of a given variable binding within the current scope
|
||||
* @param the name to which the desired variable value has been bound
|
||||
* @return the ExprResult which has been bound to the variable with
|
||||
* the given name
|
||||
**/
|
||||
virtual ExprResult* getVariable(String& name) = 0;
|
||||
|
||||
/**
|
||||
* Returns the Stack of context NodeSets
|
||||
* @return the Stack of context NodeSets
|
||||
**/
|
||||
virtual Stack* getNodeSetStack() = 0;
|
||||
|
||||
virtual MBool isStripSpaceAllowed(Node* node) = 0;
|
||||
|
||||
/**
|
||||
* Returns a call to the function that has the given name.
|
||||
* This method is used for XPath Extension Functions.
|
||||
* @return the FunctionCall for the function with the given name.
|
||||
**/
|
||||
virtual FunctionCall* resolveFunctionCall(const String& name) = 0;
|
||||
|
||||
/**
|
||||
* Returns the namespace URI for the given namespace prefix, this method should
|
||||
* only be called for determining a namespace declared within the context
|
||||
* (ie. the stylesheet)
|
||||
**/
|
||||
virtual void getNameSpaceURIFromPrefix(const String& aPrefix, String& aNamespaceURI) = 0;
|
||||
}; //-- ContextState
|
||||
|
||||
/*
|
||||
* necessary prototypes
|
||||
*/
|
||||
class txIParseContext;
|
||||
class txIMatchContext;
|
||||
class txIEvalContext;
|
||||
|
||||
/**
|
||||
* A Base Class for all XSL Expressions
|
||||
|
@ -106,7 +67,9 @@ public:
|
|||
/**
|
||||
* Virtual destructor, important for subclasses
|
||||
**/
|
||||
virtual ~Expr();
|
||||
virtual ~Expr()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
|
@ -115,19 +78,7 @@ public:
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0;
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Expr based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual ExprResult* evaluate(txIEvalContext* aContext) = 0;
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
|
@ -141,6 +92,14 @@ public:
|
|||
|
||||
}; //-- Expr
|
||||
|
||||
#define TX_DECL_EVALUATE \
|
||||
ExprResult* evaluate(txIEvalContext* aContext)
|
||||
|
||||
#define TX_DECL_EXPR \
|
||||
TX_DECL_EVALUATE; \
|
||||
void toString(String& aDest)
|
||||
|
||||
|
||||
/**
|
||||
* This class represents a FunctionCall as defined by the XPath 1.0
|
||||
* Recommendation.
|
||||
|
@ -157,22 +116,22 @@ public:
|
|||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0;
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual ExprResult* evaluate(txIEvalContext* aContext) = 0;
|
||||
virtual void toString(String& dest);
|
||||
|
||||
/**
|
||||
* Adds the given parameter to this FunctionCall's parameter list
|
||||
* @param expr the Expr to add to this FunctionCall's parameter list
|
||||
**/
|
||||
void addParam(Expr* expr);
|
||||
nsresult addParam(Expr* aExpr);
|
||||
|
||||
virtual MBool requireParams(int paramCountMin, ContextState* cs);
|
||||
|
||||
virtual MBool requireParams(int paramCountMin,
|
||||
int paramCountMax,
|
||||
ContextState* cs);
|
||||
/*
|
||||
* XXX txIEvalContext should be txIParseContest, bug 143291
|
||||
*/
|
||||
virtual MBool requireParams(int aParamCountMin, txIEvalContext* aContext);
|
||||
virtual MBool requireParams(int aParamCountMin,
|
||||
int aParamCountMax,
|
||||
txIEvalContext* aContext);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -185,24 +144,24 @@ protected:
|
|||
* Evaluates the given Expression and converts its result to a String.
|
||||
* The value is appended to the given destination String
|
||||
*/
|
||||
void evaluateToString(Expr* aExpr, Node* aContext,
|
||||
ContextState* aCs, String& aDest);
|
||||
void evaluateToString(Expr* aExpr, txIEvalContext* aContext,
|
||||
String& aDest);
|
||||
|
||||
/*
|
||||
* Evaluates the given Expression and converts its result to a number.
|
||||
*/
|
||||
double evaluateToNumber(Expr* aExpr, Node* aContext, ContextState* aCs);
|
||||
double evaluateToNumber(Expr* aExpr, txIEvalContext* aContext);
|
||||
|
||||
/*
|
||||
* Evaluates the given Expression and converts its result to a boolean.
|
||||
*/
|
||||
MBool evaluateToBoolean(Expr* aExpr, Node* aContext, ContextState* aCs);
|
||||
MBool evaluateToBoolean(Expr* aExpr, txIEvalContext* aContext);
|
||||
|
||||
/*
|
||||
* Evaluates the given Expression and converts its result to a NodeSet.
|
||||
* If the result is not a NodeSet NULL is returned.
|
||||
*/
|
||||
NodeSet* evaluateToNodeSet(Expr* aExpr, Node* aContext, ContextState* aCs);
|
||||
NodeSet* evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext);
|
||||
|
||||
String name;
|
||||
}; //-- FunctionCall
|
||||
|
@ -224,172 +183,91 @@ public:
|
|||
**/
|
||||
void addExpr(Expr* expr);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
List expressions;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This class represents a NodeTestExpr as defined by the XSL
|
||||
* Working Draft
|
||||
**/
|
||||
class NodeExpr : public Expr {
|
||||
|
||||
/*
|
||||
* This class represents a NodeTest as defined by the XPath spec
|
||||
*/
|
||||
class txNodeTest
|
||||
{
|
||||
public:
|
||||
virtual ~txNodeTest() {}
|
||||
/*
|
||||
* Virtual methods
|
||||
* pretty much a txPattern, but not supposed to be used
|
||||
* standalone. The NodeTest node() is different to the
|
||||
* Pattern "node()" (document node isn't matched)
|
||||
*/
|
||||
virtual MBool matches(Node* aNode, txIMatchContext* aContext) = 0;
|
||||
virtual double getDefaultPriority() = 0;
|
||||
virtual void toString(String& aDest) = 0;
|
||||
};
|
||||
|
||||
//-- NodeExpr Types
|
||||
//-- LF - changed from const short to enum
|
||||
enum NodeExprType {
|
||||
ATTRIBUTE_EXPR = 1,
|
||||
ELEMENT_EXPR,
|
||||
TEXT_EXPR,
|
||||
COMMENT_EXPR,
|
||||
PI_EXPR,
|
||||
NODE_EXPR
|
||||
#define TX_DECL_NODE_TEST \
|
||||
MBool matches(Node* aNode, txIMatchContext* aContext); \
|
||||
double getDefaultPriority(); \
|
||||
void toString(String& aDest)
|
||||
|
||||
/*
|
||||
* This class represents a NameTest as defined by the XPath spec
|
||||
*/
|
||||
class txNameTest : public txNodeTest
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Creates a new txNameTest with the given type and the given
|
||||
* principal node type
|
||||
*/
|
||||
txNameTest(txAtom* aPrefix, txAtom* aLocalName, PRInt32 aNSID,
|
||||
Node::NodeType aNodeType);
|
||||
|
||||
~txNameTest();
|
||||
|
||||
TX_DECL_NODE_TEST;
|
||||
|
||||
private:
|
||||
txAtom* mPrefix;
|
||||
txAtom* mLocalName;
|
||||
PRInt32 mNamespace;
|
||||
Node::NodeType mNodeType;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class represents a NodeType as defined by the XPath spec
|
||||
*/
|
||||
class txNodeTypeTest : public txNodeTest
|
||||
{
|
||||
public:
|
||||
enum NodeType {
|
||||
COMMENT_TYPE,
|
||||
TEXT_TYPE,
|
||||
PI_TYPE,
|
||||
NODE_TYPE
|
||||
};
|
||||
|
||||
virtual ~NodeExpr() {};
|
||||
/*
|
||||
* Creates a new txNodeTypeTest of the given type
|
||||
*/
|
||||
txNodeTypeTest(NodeType aNodeType);
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
~txNodeTypeTest();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs) = 0;
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs) = 0;
|
||||
virtual void toString(String& dest) = 0;
|
||||
|
||||
}; //-- NodeExpr
|
||||
|
||||
/**
|
||||
* This class represents a AttributeExpr as defined by the XSL
|
||||
* Working Draft
|
||||
**/
|
||||
class AttributeExpr : public NodeExpr {
|
||||
|
||||
public:
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
AttributeExpr(String& name);
|
||||
|
||||
/**
|
||||
* Virtual methods from NodeExpr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
|
||||
static const String WILD_CARD;
|
||||
|
||||
String prefix;
|
||||
String name;
|
||||
MBool isNameWild;
|
||||
MBool isNamespaceWild;
|
||||
|
||||
}; //-- AttributeExpr
|
||||
|
||||
/**
|
||||
*
|
||||
**/
|
||||
class BasicNodeExpr : public NodeExpr {
|
||||
|
||||
public:
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
/**
|
||||
* Creates a new BasicNodeExpr of the given type
|
||||
**/
|
||||
BasicNodeExpr(NodeExprType nodeExprType);
|
||||
|
||||
/**
|
||||
/*
|
||||
* Sets the name of the node to match. Only availible for pi nodes
|
||||
**/
|
||||
void setNodeName(const String& name);
|
||||
*/
|
||||
void setNodeName(const String& aName);
|
||||
|
||||
/**
|
||||
* Virtual methods from NodeExpr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
TX_DECL_NODE_TEST;
|
||||
|
||||
private:
|
||||
NodeExprType type;
|
||||
String nodeName;
|
||||
MBool nodeNameSet;
|
||||
}; //-- BasicNodeExpr
|
||||
|
||||
/**
|
||||
* This class represents a ElementExpr as defined by the XSL
|
||||
* Working Draft
|
||||
**/
|
||||
class ElementExpr : public NodeExpr {
|
||||
|
||||
public:
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
ElementExpr(String& name);
|
||||
|
||||
/**
|
||||
* Virtual methods from NodeExpr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
|
||||
static const String WILD_CARD;
|
||||
|
||||
String name;
|
||||
MBool isNamespaceWild;
|
||||
MBool isNameWild;
|
||||
String prefix;
|
||||
|
||||
}; //-- ElementExpr
|
||||
|
||||
/**
|
||||
* This class represents a TextExpr, which only matches any text node
|
||||
**/
|
||||
class TextExpr : public NodeExpr {
|
||||
|
||||
public:
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
/**
|
||||
* Virtual methods from NodeExpr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
}; //-- TextExpr
|
||||
NodeType mNodeType;
|
||||
txAtom* mNodeName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an ordered list of Predicates,
|
||||
|
@ -415,8 +293,7 @@ public:
|
|||
**/
|
||||
void add(Expr* expr);
|
||||
|
||||
|
||||
void evaluatePredicates(NodeSet* nodes, ContextState* cs);
|
||||
void evaluatePredicates(NodeSet* aNodes, txIMatchContext* aContext);
|
||||
|
||||
/**
|
||||
* returns true if this predicate list is empty
|
||||
|
@ -433,7 +310,7 @@ public:
|
|||
**/
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
protected:
|
||||
//-- list of predicates
|
||||
List predicates;
|
||||
}; //-- PredicateList
|
||||
|
@ -444,7 +321,7 @@ public:
|
|||
|
||||
// Axis Identifier Types
|
||||
//-- LF changed from static const short to enum
|
||||
enum _LocationStepType {
|
||||
enum LocationStepType {
|
||||
ANCESTOR_AXIS = 0,
|
||||
ANCESTOR_OR_SELF_AXIS,
|
||||
ATTRIBUTE_AXIS,
|
||||
|
@ -465,28 +342,24 @@ public:
|
|||
* @param nodeExpr the NodeExpr to use when matching Nodes
|
||||
* @param axisIdentifier the Axis Identifier in which to search for nodes
|
||||
**/
|
||||
LocationStep(NodeExpr* nodeExpr, short axisIdentifier);
|
||||
LocationStep(txNodeTest* aNodeTest, LocationStepType aAxisIdentifier);
|
||||
|
||||
/**
|
||||
* Destructor, will delete all predicates and the given NodeExpr
|
||||
**/
|
||||
virtual ~LocationStep();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
|
||||
NodeExpr* nodeExpr;
|
||||
short axisIdentifier;
|
||||
txNodeTest* mNodeTest;
|
||||
LocationStepType mAxisIdentifier;
|
||||
|
||||
void fromDescendants(Node* context, ContextState* cs, NodeSet* nodes);
|
||||
void fromDescendantsRev(Node* context, ContextState* cs, NodeSet* nodes);
|
||||
void fromDescendants(Node* node, txIMatchContext* aContext,
|
||||
NodeSet* nodes);
|
||||
void fromDescendantsRev(Node* node, txIMatchContext* aContext,
|
||||
NodeSet* nodes);
|
||||
|
||||
}; //-- LocationStep
|
||||
|
||||
|
@ -499,20 +372,14 @@ public:
|
|||
* Creates a new FilterExpr using the given Expr
|
||||
* @param expr the Expr to use for evaluation
|
||||
**/
|
||||
FilterExpr(Expr* expr);
|
||||
FilterExpr(Expr* aExpr);
|
||||
|
||||
/**
|
||||
* Destructor, will delete all predicates and the given Expr
|
||||
**/
|
||||
virtual ~FilterExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
Expr* expr;
|
||||
|
@ -526,11 +393,7 @@ public:
|
|||
|
||||
NumberExpr(double dbl);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -546,11 +409,7 @@ public:
|
|||
|
||||
StringExpr(const String& value);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -575,11 +434,7 @@ public:
|
|||
AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~AdditiveExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
short op;
|
||||
|
@ -597,11 +452,7 @@ public:
|
|||
UnaryExpr(Expr* expr);
|
||||
~UnaryExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
Expr* expr;
|
||||
|
@ -621,11 +472,7 @@ public:
|
|||
BooleanExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~BooleanExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
short op;
|
||||
|
@ -652,11 +499,7 @@ public:
|
|||
MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~MultiplicativeExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
short op;
|
||||
|
@ -692,11 +535,7 @@ public:
|
|||
RelationalExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~RelationalExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
short op;
|
||||
|
@ -714,18 +553,16 @@ class VariableRefExpr : public Expr {
|
|||
|
||||
public:
|
||||
|
||||
VariableRefExpr(const String& name);
|
||||
VariableRefExpr(txAtom* aPrefix, txAtom* aLocalName, PRInt32 aNSID);
|
||||
~VariableRefExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
String name;
|
||||
|
||||
}; //-- VariableRefExpr
|
||||
txAtom* mPrefix;
|
||||
txAtom* mLocalName;
|
||||
PRInt32 mNamespace;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a PathExpr
|
||||
|
@ -755,32 +592,25 @@ public:
|
|||
**/
|
||||
void addExpr(Expr* expr, PathOperator pathOp);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
|
||||
static const String RTF_INVALID_OP;
|
||||
static const String NODESET_EXPECTED;
|
||||
struct PathExprItem {
|
||||
Expr* expr;
|
||||
PathOperator pathOp;
|
||||
};
|
||||
|
||||
List expressions;
|
||||
List expressions;
|
||||
|
||||
/**
|
||||
* Selects from the descendants of the context node
|
||||
* all nodes that match the Expr
|
||||
* -- this will be moving to a Utility class
|
||||
**/
|
||||
void evalDescendants(Expr* expr,
|
||||
Node* context,
|
||||
ContextState* cs,
|
||||
NodeSet* resNodes);
|
||||
/*
|
||||
* Selects from the descendants of the context node
|
||||
* all nodes that match the Expr
|
||||
*/
|
||||
void evalDescendants(Expr* aStep, Node* aNode,
|
||||
txIMatchContext* aContext,
|
||||
NodeSet* resNodes);
|
||||
|
||||
}; //-- PathExpr
|
||||
|
||||
|
@ -797,13 +627,7 @@ public:
|
|||
*/
|
||||
RootExpr(MBool aSerialize);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
// When a RootExpr is used in a PathExpr it shouldn't be serialized
|
||||
|
@ -834,13 +658,7 @@ public:
|
|||
**/
|
||||
void addExpr(Expr* expr);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
TX_DECL_EXPR;
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -41,25 +41,16 @@
|
|||
#include "ExprParser.h"
|
||||
#include "FunctionLib.h"
|
||||
#include "Names.h"
|
||||
|
||||
/**
|
||||
* Creates a new ExprParser
|
||||
**/
|
||||
ExprParser::ExprParser() {};
|
||||
|
||||
/**
|
||||
* Default Destructor
|
||||
**/
|
||||
ExprParser::~ExprParser() {};
|
||||
#include "txAtoms.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/**
|
||||
* Creates an Attribute Value Template using the given value
|
||||
* This should move to XSLProcessor class
|
||||
**/
|
||||
AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
||||
(const String& attValue)
|
||||
(const String& attValue, txIParseContext* aContext)
|
||||
{
|
||||
|
||||
AttributeValueTemplate* avt = new AttributeValueTemplate();
|
||||
|
||||
if (attValue.isEmpty())
|
||||
|
@ -116,7 +107,8 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
|||
case '}':
|
||||
if (inExpr) {
|
||||
inExpr = MB_FALSE;
|
||||
Expr* expr = createExpr(buffer);
|
||||
ExprLexer lexer(buffer);
|
||||
Expr* expr = createExpr(lexer, aContext);
|
||||
if (!expr) {
|
||||
delete avt;
|
||||
return 0;
|
||||
|
@ -154,18 +146,14 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
|||
|
||||
} //-- createAttributeValueTemplate
|
||||
|
||||
Expr* ExprParser::createExpr(const String& aExpression)
|
||||
Expr* ExprParser::createExpr(const String& aExpression,
|
||||
txIParseContext* aContext)
|
||||
{
|
||||
ExprLexer lexer(aExpression);
|
||||
return createExpr(lexer);
|
||||
Expr* expr = createExpr(lexer, aContext);
|
||||
return expr;
|
||||
} //-- createExpr
|
||||
|
||||
Pattern* ExprParser::createPattern(const String& aPattern)
|
||||
{
|
||||
ExprLexer lexer(aPattern);
|
||||
return createUnionExpr(lexer);
|
||||
} //-- createPatternExpr
|
||||
|
||||
//--------------------/
|
||||
//- Private Methods -/
|
||||
//-------------------/
|
||||
|
@ -221,8 +209,8 @@ Expr* ExprParser::createBinaryExpr (Expr* left, Expr* right, Token* op) {
|
|||
} //-- createBinaryExpr
|
||||
|
||||
|
||||
Expr* ExprParser::createExpr(ExprLexer& lexer) {
|
||||
|
||||
Expr* ExprParser::createExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||
{
|
||||
MBool done = MB_FALSE;
|
||||
|
||||
Expr* expr = 0;
|
||||
|
@ -238,7 +226,7 @@ Expr* ExprParser::createExpr(ExprLexer& lexer) {
|
|||
lexer.nextToken();
|
||||
}
|
||||
|
||||
expr = createUnionExpr(lexer);
|
||||
expr = createUnionExpr(lexer, aContext);
|
||||
if (!expr)
|
||||
break;
|
||||
|
||||
|
@ -299,21 +287,33 @@ Expr* ExprParser::createExpr(ExprLexer& lexer) {
|
|||
|
||||
} //-- createExpr
|
||||
|
||||
Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
|
||||
|
||||
Expr* ExprParser::createFilterExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||
{
|
||||
Token* tok = lexer.nextToken();
|
||||
|
||||
Expr* expr = 0;
|
||||
switch (tok->type) {
|
||||
case Token::FUNCTION_NAME :
|
||||
lexer.pushBack();
|
||||
expr = createFunctionCall(lexer);
|
||||
expr = createFunctionCall(lexer, aContext);
|
||||
break;
|
||||
case Token::VAR_REFERENCE :
|
||||
expr = new VariableRefExpr(tok->value);
|
||||
{
|
||||
txAtom *prefix, *lName;
|
||||
PRInt32 nspace;
|
||||
nsresult rv = resolveQName(tok->value, prefix, aContext,
|
||||
lName, nspace);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report namespace resolve failed
|
||||
return 0;
|
||||
}
|
||||
expr = new VariableRefExpr(prefix, lName, nspace);
|
||||
TX_IF_RELEASE_ATOM(prefix);
|
||||
TX_IF_RELEASE_ATOM(lName);
|
||||
}
|
||||
break;
|
||||
case Token::L_PAREN:
|
||||
expr = createExpr(lexer);
|
||||
expr = createExpr(lexer, aContext);
|
||||
if (!expr)
|
||||
return 0;
|
||||
|
||||
|
@ -347,7 +347,7 @@ Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
|
|||
FilterExpr* filterExpr = new FilterExpr(expr);
|
||||
|
||||
//-- handle predicates
|
||||
if (!parsePredicates(filterExpr, lexer)) {
|
||||
if (!parsePredicates(filterExpr, lexer, aContext)) {
|
||||
delete filterExpr;
|
||||
return 0;
|
||||
}
|
||||
|
@ -358,8 +358,9 @@ Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
|
|||
|
||||
} //-- createFilterExpr
|
||||
|
||||
FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) {
|
||||
|
||||
Expr* ExprParser::createFunctionCall(ExprLexer& lexer,
|
||||
txIParseContext* aContext)
|
||||
{
|
||||
FunctionCall* fnCall = 0;
|
||||
|
||||
Token* tok = lexer.nextToken();
|
||||
|
@ -368,11 +369,11 @@ FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
String fnName = tok->value;
|
||||
|
||||
//-- compare function names
|
||||
//-- * we should hash these names for speed
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (XPathNames::BOOLEAN_FN.isEqual(tok->value)) {
|
||||
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_BOOLEAN);
|
||||
}
|
||||
|
@ -455,24 +456,44 @@ FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) {
|
|||
fnCall = new NumberFunctionCall(NumberFunctionCall::FLOOR);
|
||||
}
|
||||
else {
|
||||
//-- Most likely an Extension Function, or error, but it's
|
||||
//-- not our job to report an invalid function call here
|
||||
fnCall = new ExtensionFunctionCall(fnName);
|
||||
txAtom *prefix, *lName;
|
||||
PRInt32 namespaceID;
|
||||
rv = resolveQName(tok->value, prefix, aContext, lName, namespaceID);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report namespace resolve failed
|
||||
return 0;
|
||||
}
|
||||
rv = aContext->resolveFunctionCall(lName, namespaceID, fnCall);
|
||||
TX_IF_RELEASE_ATOM(prefix);
|
||||
TX_IF_RELEASE_ATOM(lName);
|
||||
if (NS_FAILED(rv) && rv != NS_ERROR_NOT_IMPLEMENTED) {
|
||||
// XXX report error unknown function call
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-- handle parametes
|
||||
if (!parseParameters(fnCall, lexer)) {
|
||||
if (!parseParameters(fnCall, lexer, aContext)) {
|
||||
delete fnCall;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
NS_ASSERTION(!fnCall, "Now is it implemented or not?");
|
||||
String err(tok->value);
|
||||
err.append(" not implemented.");
|
||||
return new StringExpr(err);
|
||||
}
|
||||
|
||||
return fnCall;
|
||||
} //-- createFunctionCall
|
||||
|
||||
LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) {
|
||||
|
||||
LocationStep* ExprParser::createLocationStep(ExprLexer& lexer,
|
||||
txIParseContext* aContext)
|
||||
{
|
||||
//-- child axis is default
|
||||
short axisIdentifier = LocationStep::CHILD_AXIS;
|
||||
NodeExpr* nodeExpr = 0;
|
||||
LocationStep::LocationStepType axisIdentifier = LocationStep::CHILD_AXIS;
|
||||
txNodeTest* nodeTest = 0;
|
||||
|
||||
//-- get Axis Identifier or AbbreviatedStep, if present
|
||||
Token* tok = lexer.peek();
|
||||
|
@ -536,44 +557,78 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) {
|
|||
//-- eat token
|
||||
lexer.nextToken();
|
||||
axisIdentifier = LocationStep::PARENT_AXIS;
|
||||
nodeExpr = new BasicNodeExpr(NodeExpr::NODE_EXPR);
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
if (!nodeTest) {
|
||||
//XXX out of memory
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case Token::SELF_NODE :
|
||||
//-- eat token
|
||||
lexer.nextToken();
|
||||
axisIdentifier = LocationStep::SELF_AXIS;
|
||||
nodeExpr = new BasicNodeExpr(NodeExpr::NODE_EXPR);
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
if (!nodeTest) {
|
||||
//XXX out of memory
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//-- get NodeTest unless AbbreviatedStep was found
|
||||
if (!nodeExpr) {
|
||||
//-- get NodeTest unless an AbbreviatedStep was found
|
||||
if (!nodeTest) {
|
||||
tok = lexer.nextToken();
|
||||
|
||||
switch (tok->type) {
|
||||
case Token::CNAME :
|
||||
// NameTest
|
||||
// XXX Namespace: handle namespaces here
|
||||
if (axisIdentifier == LocationStep::ATTRIBUTE_AXIS)
|
||||
nodeExpr = new AttributeExpr(tok->value);
|
||||
else
|
||||
nodeExpr = new ElementExpr(tok->value);
|
||||
{
|
||||
// resolve QName
|
||||
txAtom *prefix, *lName;
|
||||
PRInt32 nspace;
|
||||
nsresult rv = resolveQName(tok->value, prefix, aContext,
|
||||
lName, nspace);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report namespace resolve failed
|
||||
return 0;
|
||||
}
|
||||
switch (axisIdentifier) {
|
||||
case LocationStep::ATTRIBUTE_AXIS:
|
||||
nodeTest = new txNameTest(prefix, lName, nspace,
|
||||
Node::ATTRIBUTE_NODE);
|
||||
break;
|
||||
default:
|
||||
nodeTest = new txNameTest(prefix, lName, nspace,
|
||||
Node::ELEMENT_NODE);
|
||||
break;
|
||||
}
|
||||
TX_IF_RELEASE_ATOM(prefix);
|
||||
TX_IF_RELEASE_ATOM(lName);
|
||||
}
|
||||
if (!nodeTest) {
|
||||
//XXX ErrorReport: out of memory
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
nodeExpr = createNodeExpr(lexer);
|
||||
if (!nodeExpr) {
|
||||
nodeTest = createNodeTypeTest(lexer);
|
||||
if (!nodeTest) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LocationStep* lstep = new LocationStep(nodeExpr, axisIdentifier);
|
||||
LocationStep* lstep = new LocationStep(nodeTest, axisIdentifier);
|
||||
if (!lstep) {
|
||||
//XXX out of memory
|
||||
delete nodeTest;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-- handle predicates
|
||||
if (!parsePredicates(lstep, lexer)) {
|
||||
if (!parsePredicates(lstep, lexer, aContext)) {
|
||||
delete lstep;
|
||||
return 0;
|
||||
}
|
||||
|
@ -585,59 +640,62 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) {
|
|||
* This method only handles comment(), text(), processing-instructing() and node()
|
||||
*
|
||||
**/
|
||||
NodeExpr* ExprParser::createNodeExpr(ExprLexer& lexer) {
|
||||
txNodeTypeTest* ExprParser::createNodeTypeTest(ExprLexer& lexer) {
|
||||
|
||||
NodeExpr* nodeExpr = 0;
|
||||
txNodeTypeTest* nodeTest = 0;
|
||||
|
||||
Token* nodeTok = lexer.nextToken();
|
||||
|
||||
switch (nodeTok->type) {
|
||||
case Token::COMMENT:
|
||||
nodeExpr = new BasicNodeExpr(NodeExpr::COMMENT_EXPR);
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::COMMENT_TYPE);
|
||||
break;
|
||||
case Token::NODE :
|
||||
nodeExpr = new BasicNodeExpr(NodeExpr::NODE_EXPR);
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
break;
|
||||
case Token::PROC_INST :
|
||||
nodeExpr = new BasicNodeExpr(NodeExpr::PI_EXPR);
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::PI_TYPE);
|
||||
break;
|
||||
case Token::TEXT :
|
||||
nodeExpr = new TextExpr();
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::TEXT_TYPE);
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
// XXX ErrorReport: unexpected token
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if (!nodeTest) {
|
||||
//XXX out of memory
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lexer.nextToken()->type != Token::L_PAREN) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: left parenthesis expected
|
||||
delete nodeExpr;
|
||||
delete nodeTest;
|
||||
return 0;
|
||||
}
|
||||
if (nodeTok->type == Token::PROC_INST &&
|
||||
lexer.peek()->type == Token::LITERAL) {
|
||||
Token* tok = lexer.nextToken();
|
||||
((BasicNodeExpr*)nodeExpr)->setNodeName(tok->value);
|
||||
nodeTest->setNodeName(tok->value);
|
||||
}
|
||||
if (lexer.nextToken()->type != Token::R_PAREN) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: right parenthesis expected (or literal for pi)
|
||||
delete nodeExpr;
|
||||
delete nodeTest;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nodeExpr;
|
||||
} //-- createNodeExpr
|
||||
return nodeTest;
|
||||
} //-- createNodeTypeTest
|
||||
|
||||
/**
|
||||
* Creates a PathExpr using the given ExprLexer
|
||||
* @param lexer the ExprLexer for retrieving Tokens
|
||||
**/
|
||||
Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
||||
|
||||
Expr* ExprParser::createPathExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||
{
|
||||
Expr* expr = 0;
|
||||
|
||||
Token* tok = lexer.peek();
|
||||
|
@ -655,10 +713,10 @@ Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
|||
if (tok->type != Token::PARENT_OP &&
|
||||
tok->type != Token::ANCESTOR_OP) {
|
||||
if (isFilterExprToken(tok)) {
|
||||
expr = createFilterExpr(lexer);
|
||||
expr = createFilterExpr(lexer, aContext);
|
||||
}
|
||||
else
|
||||
expr = createLocationStep(lexer);
|
||||
expr = createLocationStep(lexer, aContext);
|
||||
|
||||
if (!expr)
|
||||
return 0;
|
||||
|
@ -702,7 +760,7 @@ Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
|||
return pathExpr;
|
||||
}
|
||||
|
||||
expr = createLocationStep(lexer);
|
||||
expr = createLocationStep(lexer, aContext);
|
||||
if (!expr) {
|
||||
delete pathExpr;
|
||||
return 0;
|
||||
|
@ -719,9 +777,9 @@ Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
|||
* XXX temporary use as top of XSLT Pattern
|
||||
* @param lexer the ExprLexer for retrieving Tokens
|
||||
**/
|
||||
Expr* ExprParser::createUnionExpr(ExprLexer& lexer) {
|
||||
|
||||
Expr* expr = createPathExpr(lexer);
|
||||
Expr* ExprParser::createUnionExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||
{
|
||||
Expr* expr = createPathExpr(lexer, aContext);
|
||||
if (!expr)
|
||||
return 0;
|
||||
|
||||
|
@ -734,7 +792,7 @@ Expr* ExprParser::createUnionExpr(ExprLexer& lexer) {
|
|||
while (lexer.peek()->type == Token::UNION_OP) {
|
||||
lexer.nextToken(); //-- eat token
|
||||
|
||||
expr = createPathExpr(lexer);
|
||||
expr = createPathExpr(lexer, aContext);
|
||||
if (!expr) {
|
||||
delete unionExpr;
|
||||
return 0;
|
||||
|
@ -791,13 +849,14 @@ MBool ExprParser::isNodeTypeToken(Token* token) {
|
|||
* @param lexer the ExprLexer to use for parsing tokens
|
||||
* @return 0 if successful, or a String pointer to the error message
|
||||
**/
|
||||
MBool ExprParser::parsePredicates(PredicateList* predicateList, ExprLexer& lexer) {
|
||||
|
||||
MBool ExprParser::parsePredicates(PredicateList* predicateList,
|
||||
ExprLexer& lexer, txIParseContext* aContext)
|
||||
{
|
||||
while (lexer.peek()->type == Token::L_BRACKET) {
|
||||
//-- eat Token
|
||||
lexer.nextToken();
|
||||
|
||||
Expr* expr = createExpr(lexer);
|
||||
Expr* expr = createExpr(lexer, aContext);
|
||||
if (!expr)
|
||||
return MB_FALSE;
|
||||
|
||||
|
@ -822,8 +881,9 @@ MBool ExprParser::parsePredicates(PredicateList* predicateList, ExprLexer& lexer
|
|||
* @param lexer the ExprLexer to use for parsing tokens
|
||||
* @return MB_TRUE if successful, or a MB_FALSE otherwise
|
||||
**/
|
||||
MBool ExprParser::parseParameters(FunctionCall* fnCall, ExprLexer& lexer) {
|
||||
|
||||
MBool ExprParser::parseParameters(FunctionCall* fnCall, ExprLexer& lexer,
|
||||
txIParseContext* aContext)
|
||||
{
|
||||
if (lexer.nextToken()->type != Token::L_PAREN) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: left parenthesis expected
|
||||
|
@ -836,11 +896,12 @@ MBool ExprParser::parseParameters(FunctionCall* fnCall, ExprLexer& lexer) {
|
|||
}
|
||||
|
||||
while (1) {
|
||||
Expr* expr = createExpr(lexer);
|
||||
Expr* expr = createExpr(lexer, aContext);
|
||||
if (!expr)
|
||||
return MB_FALSE;
|
||||
|
||||
fnCall->addParam(expr);
|
||||
if (fnCall)
|
||||
fnCall->addParam(expr);
|
||||
|
||||
switch (lexer.nextToken()->type) {
|
||||
case Token::R_PAREN :
|
||||
|
@ -887,5 +948,35 @@ short ExprParser::precedenceLevel(short tokenType) {
|
|||
break;
|
||||
}
|
||||
return 0;
|
||||
} //-- precedenceLevel
|
||||
}
|
||||
|
||||
nsresult ExprParser::resolveQName(const String& aQName,
|
||||
txAtom*& aPrefix, txIParseContext* aContext,
|
||||
txAtom*& aLocalName, PRInt32& aNamespace)
|
||||
{
|
||||
aNamespace = kNameSpaceID_None;
|
||||
String prefix, lName;
|
||||
int idx = aQName.indexOf(':');
|
||||
if (idx > 0) {
|
||||
aQName.subString(0, idx, prefix);
|
||||
aPrefix = TX_GET_ATOM(prefix);
|
||||
if (!aPrefix) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
aQName.subString(idx + 1, lName);
|
||||
aLocalName = TX_GET_ATOM(lName);
|
||||
if (!aLocalName) {
|
||||
TX_RELEASE_ATOM(aPrefix);
|
||||
aPrefix = 0;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return aContext->resolveNamespacePrefix(aPrefix, aNamespace);
|
||||
}
|
||||
// the lexer dealt with idx == 0
|
||||
aPrefix = 0;
|
||||
aLocalName = TX_GET_ATOM(aQName);
|
||||
if (!aLocalName) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -36,59 +36,61 @@
|
|||
#include "ExprLexer.h"
|
||||
#include "Expr.h"
|
||||
#include "List.h"
|
||||
class txIParseContext;
|
||||
|
||||
class ExprParser {
|
||||
|
||||
class ExprParser
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new ExprParser
|
||||
**/
|
||||
ExprParser();
|
||||
|
||||
/**
|
||||
* destroys the ExprParser
|
||||
**/
|
||||
~ExprParser();
|
||||
|
||||
Expr* createExpr(const String& aExpression);
|
||||
Pattern* createPattern(const String& aPattern);
|
||||
static Expr* createExpr(const String& aExpression,
|
||||
txIParseContext* aContext);
|
||||
|
||||
/**
|
||||
* Creates an Attribute Value Template using the given value
|
||||
**/
|
||||
AttributeValueTemplate* createAttributeValueTemplate(const String& attValue);
|
||||
static AttributeValueTemplate* createAttributeValueTemplate
|
||||
(const String& attValue, txIParseContext* aContext);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Expr* createBinaryExpr (Expr* left, Expr* right, Token* op);
|
||||
Expr* createExpr (ExprLexer& lexer);
|
||||
Expr* createFilterExpr (ExprLexer& lexer);
|
||||
FunctionCall* createFunctionCall (ExprLexer& lexer);
|
||||
LocationStep* createLocationStep (ExprLexer& lexer);
|
||||
NodeExpr* createNodeExpr (ExprLexer& lexer);
|
||||
Expr* createPathExpr (ExprLexer& lexer);
|
||||
Expr* createUnionExpr (ExprLexer& lexer);
|
||||
|
||||
MBool isFilterExprToken (Token* tok);
|
||||
MBool isLocationStepToken (Token* tok);
|
||||
MBool isNodeTypeToken (Token* tok);
|
||||
|
||||
static short precedenceLevel (short tokenType);
|
||||
protected:
|
||||
static Expr* createBinaryExpr(Expr* left, Expr* right, Token* op);
|
||||
static Expr* createExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||
static Expr* createFilterExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||
static Expr* createFunctionCall(ExprLexer& lexer,
|
||||
txIParseContext* aContext);
|
||||
static LocationStep* createLocationStep(ExprLexer& lexer,
|
||||
txIParseContext* aContext);
|
||||
static txNodeTypeTest* createNodeTypeTest(ExprLexer& lexer);
|
||||
static Expr* createPathExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||
static Expr* createUnionExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||
|
||||
static MBool isFilterExprToken (Token* tok);
|
||||
static MBool isLocationStepToken(Token* tok);
|
||||
static MBool isNodeTypeToken (Token* tok);
|
||||
|
||||
static short precedenceLevel (short tokenType);
|
||||
|
||||
/**
|
||||
* Using the given lexer, parses the tokens if they represent a predicate list
|
||||
* If an error occurs a non-zero String pointer will be returned containing the
|
||||
* error message.
|
||||
* Resolve a QName, given the mContext parse context.
|
||||
* Returns prefix and localName as well as namespace ID
|
||||
**/
|
||||
static nsresult resolveQName(const String& aQName, txAtom*& aPrefix,
|
||||
txIParseContext* aContext,
|
||||
txAtom*& aLocalName, PRInt32& aNamespace);
|
||||
|
||||
/**
|
||||
* Using the given lexer, parses the tokens if they represent a
|
||||
* predicate list
|
||||
* If an error occurs a non-zero String pointer will be returned
|
||||
* containing the error message.
|
||||
* @param predicateList, the PredicateList to add predicate expressions to
|
||||
* @param lexer the ExprLexer to use for parsing tokens
|
||||
* @return 0 if successful, or a String pointer to the error message
|
||||
**/
|
||||
MBool parsePredicates(PredicateList* predicateList, ExprLexer& lexer);
|
||||
MBool parseParameters(FunctionCall* fnCall, ExprLexer& lexer);
|
||||
|
||||
static MBool parsePredicates(PredicateList* predicateList,
|
||||
ExprLexer& lexer, txIParseContext* aContext);
|
||||
static MBool parseParameters(FunctionCall* fnCall,
|
||||
ExprLexer& lexer, txIParseContext* aContext);
|
||||
|
||||
}; //-- ExprParser
|
||||
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is XSL:P XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Visco.
|
||||
* Portions created by Keith Visco are Copyright (C) 1999, 2000 Keith Visco.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
|
||||
|
||||
const String ExtensionFunctionCall::UNDEFINED_FUNCTION = "Undefined Function: ";
|
||||
|
||||
/**
|
||||
* Creates an ExtensionFunctionCall with the given function name.
|
||||
* @param name the name of the extension function which to invoke
|
||||
**/
|
||||
ExtensionFunctionCall::ExtensionFunctionCall(const String& name) : FunctionCall(name)
|
||||
{
|
||||
this->fname = name;
|
||||
this->fnCall = 0;
|
||||
|
||||
} //-- ExtensionFunctionCall
|
||||
|
||||
/**
|
||||
* Deletes an instance of ExtensionFunctioncall
|
||||
**/
|
||||
ExtensionFunctionCall::~ExtensionFunctionCall() {
|
||||
delete fnCall;
|
||||
} //-- ~ExtensionFunctionCall
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* ExtensionFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
//-- check for existing function call resolution
|
||||
|
||||
if (!fnCall) {
|
||||
fnCall = cs->resolveFunctionCall(fname);
|
||||
|
||||
if (!fnCall) {
|
||||
String err(UNDEFINED_FUNCTION);
|
||||
err.append(fname);
|
||||
return new StringResult(err);
|
||||
}
|
||||
|
||||
//copy parameters
|
||||
ListIterator* iter = params.iterator();
|
||||
while (iter->hasNext()) {
|
||||
fnCall->addParam( new ExprWrapper( (Expr*) iter->next() ) );
|
||||
}
|
||||
delete iter;
|
||||
}
|
||||
|
||||
//-- delegate
|
||||
return fnCall->evaluate(context, cs);
|
||||
|
||||
} //-- evaluate
|
||||
|
||||
//---------------------------------/
|
||||
//- Implementation of ExprWrapper -/
|
||||
//---------------------------------/
|
||||
|
||||
/**
|
||||
* Creates a new ExprWrapper for the given Expr
|
||||
**/
|
||||
ExprWrapper::ExprWrapper(Expr* expr) {
|
||||
this->expr = expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for ExprWrapper
|
||||
**/
|
||||
ExprWrapper::~ExprWrapper() {
|
||||
//-- DO NOTHING!
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* ExprWrapper::evaluate(Node* context, ContextState* cs) {
|
||||
//-- just delegate
|
||||
if (!expr) return 0; // <-- hopefully this will never happen
|
||||
return expr->evaluate(context, cs);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void ExprWrapper::toString(String& str) {
|
||||
//-- just delegate
|
||||
if (expr) expr->toString(str);
|
||||
} //-- toString
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
//-- Implementation of FilterExpr --/
|
||||
|
||||
|
@ -56,24 +57,24 @@ FilterExpr::~FilterExpr() {
|
|||
* @return the result of the evaluation
|
||||
* @see Expr
|
||||
**/
|
||||
ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
if (!context || !expr)
|
||||
ExprResult* FilterExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
if (!aContext || !expr)
|
||||
return new NodeSet;
|
||||
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
ExprResult* exprResult = expr->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return 0;
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
// Result is a nodeset, filter it.
|
||||
evaluatePredicates((NodeSet*)exprResult, cs);
|
||||
evaluatePredicates((NodeSet*)exprResult, aContext);
|
||||
}
|
||||
else if(!isEmpty()) {
|
||||
// We can't filter a non-nodeset
|
||||
String err("Expecting nodeset as result of: ");
|
||||
expr->toString(err);
|
||||
cs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_EVAL_FAILED);
|
||||
delete exprResult;
|
||||
return new NodeSet;
|
||||
}
|
||||
|
@ -81,40 +82,6 @@ ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) {
|
|||
return exprResult;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double FilterExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
NS_ASSERTION(0, "FilterExpr is not allowed in Patterns");
|
||||
|
||||
if (isEmpty())
|
||||
return expr->getDefaultPriority(node, context, cs);
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool FilterExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
if (!expr)
|
||||
return MB_FALSE;
|
||||
|
||||
ExprResult* exprResult = evaluate(node, cs);
|
||||
if (!exprResult)
|
||||
return MB_FALSE;
|
||||
|
||||
MBool result = MB_FALSE;
|
||||
if(exprResult->getResultType() == ExprResult::NODESET)
|
||||
result = ((NodeSet*)exprResult)->contains(node);
|
||||
|
||||
delete exprResult;
|
||||
return result;
|
||||
|
||||
} //-- matches
|
||||
|
||||
/**
|
||||
* Creates a String representation of this Expr
|
||||
* @param str the destination String to append to
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/**
|
||||
* This class represents a FunctionCall as defined by the XSL Working Draft
|
||||
|
@ -77,50 +78,22 @@ FunctionCall::~FunctionCall()
|
|||
* Adds the given parameter to this FunctionCall's parameter list
|
||||
* @param expr the Expr to add to this FunctionCall's parameter list
|
||||
**/
|
||||
void FunctionCall::addParam(Expr* expr)
|
||||
nsresult FunctionCall::addParam(Expr* aExpr)
|
||||
{
|
||||
if (expr)
|
||||
params.add(expr);
|
||||
if (aExpr)
|
||||
params.add(aExpr);
|
||||
return NS_OK;
|
||||
} //-- addParam
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Expr based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double FunctionCall::getDefaultPriority(Node* node,
|
||||
Node* context,
|
||||
ContextState* cs)
|
||||
{
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool FunctionCall::matches(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
MBool result = MB_FALSE;
|
||||
ExprResult* exprResult = evaluate(node, cs);
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* nodes = (NodeSet*)exprResult;
|
||||
result = (nodes->contains(node));
|
||||
}
|
||||
delete exprResult;
|
||||
return result;
|
||||
} //-- matches
|
||||
|
||||
/*
|
||||
* Evaluates the given Expression and converts its result to a String.
|
||||
* The value is appended to the given destination String
|
||||
*/
|
||||
void FunctionCall::evaluateToString(Expr* aExpr,
|
||||
Node* aContext,
|
||||
ContextState* aCs,
|
||||
void FunctionCall::evaluateToString(Expr* aExpr, txIEvalContext* aContext,
|
||||
String& aDest)
|
||||
{
|
||||
NS_ASSERTION(aExpr, "missing expression");
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return;
|
||||
|
||||
|
@ -131,12 +104,10 @@ void FunctionCall::evaluateToString(Expr* aExpr,
|
|||
/*
|
||||
* Evaluates the given Expression and converts its result to a number.
|
||||
*/
|
||||
double FunctionCall::evaluateToNumber(Expr* aExpr,
|
||||
Node* aContext,
|
||||
ContextState* aCs)
|
||||
double FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(aExpr, "missing expression");
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return Double::NaN;
|
||||
|
||||
|
@ -148,12 +119,10 @@ double FunctionCall::evaluateToNumber(Expr* aExpr,
|
|||
/*
|
||||
* Evaluates the given Expression and converts its result to a boolean.
|
||||
*/
|
||||
MBool FunctionCall::evaluateToBoolean(Expr* aExpr,
|
||||
Node* aContext,
|
||||
ContextState* aCs)
|
||||
MBool FunctionCall::evaluateToBoolean(Expr* aExpr, txIEvalContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(aExpr, "missing expression");
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return MB_FALSE;
|
||||
|
||||
|
@ -166,18 +135,16 @@ MBool FunctionCall::evaluateToBoolean(Expr* aExpr,
|
|||
* Evaluates the given Expression and converts its result to a NodeSet.
|
||||
* If the result is not a NodeSet NULL is returned.
|
||||
*/
|
||||
NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr,
|
||||
Node* aContext,
|
||||
ContextState* aCs)
|
||||
NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(aExpr, "Missing expression to evaluate");
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return 0;
|
||||
|
||||
if (exprResult->getResultType() != ExprResult::NODESET) {
|
||||
String err("NodeSet expected as argument");
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
delete exprResult;
|
||||
return 0;
|
||||
}
|
||||
|
@ -190,13 +157,13 @@ NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr,
|
|||
**/
|
||||
MBool FunctionCall::requireParams (int paramCountMin,
|
||||
int paramCountMax,
|
||||
ContextState* cs)
|
||||
txIEvalContext* aContext)
|
||||
{
|
||||
int argc = params.getLength();
|
||||
if ((argc < paramCountMin) || (argc > paramCountMax)) {
|
||||
String err(INVALID_PARAM_COUNT);
|
||||
toString(err);
|
||||
cs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
return MB_FALSE;
|
||||
}
|
||||
return MB_TRUE;
|
||||
|
@ -205,13 +172,13 @@ MBool FunctionCall::requireParams (int paramCountMin,
|
|||
/**
|
||||
* Called to check number of parameters
|
||||
**/
|
||||
MBool FunctionCall::requireParams(int paramCountMin, ContextState* cs)
|
||||
MBool FunctionCall::requireParams(int paramCountMin, txIEvalContext* aContext)
|
||||
{
|
||||
int argc = params.getLength();
|
||||
if (argc < paramCountMin) {
|
||||
String err(INVALID_PARAM_COUNT);
|
||||
toString(err);
|
||||
cs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
return MB_FALSE;
|
||||
}
|
||||
return MB_TRUE;
|
||||
|
|
|
@ -125,14 +125,7 @@ public:
|
|||
**/
|
||||
BooleanFunctionCall(BooleanFunctions aType);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
||||
TX_DECL_EVALUATE;
|
||||
|
||||
private:
|
||||
BooleanFunctions mType;
|
||||
|
@ -148,14 +141,7 @@ public:
|
|||
ErrorFunctionCall();
|
||||
ErrorFunctionCall(const String& errorMsg);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
TX_DECL_EVALUATE;
|
||||
|
||||
void setErrorMessage(String& errorMsg);
|
||||
|
||||
|
@ -165,89 +151,6 @@ private:
|
|||
|
||||
}; //-- ErrorFunctionCall
|
||||
|
||||
|
||||
/**
|
||||
* Used for extension functions
|
||||
**/
|
||||
class ExtensionFunctionCall : public FunctionCall {
|
||||
|
||||
public:
|
||||
|
||||
static const String UNDEFINED_FUNCTION;
|
||||
|
||||
/**
|
||||
* Creates a new ExtensionFunctionCall with the given function name
|
||||
* @param name the name of the extension function
|
||||
**/
|
||||
ExtensionFunctionCall(const String& name);
|
||||
|
||||
/**
|
||||
* Destructor for extension function call
|
||||
**/
|
||||
virtual ~ExtensionFunctionCall();
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
private:
|
||||
|
||||
String fname;
|
||||
FunctionCall* fnCall;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used by ExtensionFunctionCall, to prevent deletion
|
||||
* of the parameter expressions, by the resolved function call. The implementation
|
||||
* for this class is in ExtensionFunctionCall.cpp
|
||||
**/
|
||||
class ExprWrapper : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new ExprWrapper for the given Expr
|
||||
**/
|
||||
ExprWrapper(Expr* expr);
|
||||
|
||||
/**
|
||||
* Destructor for ExprWrapper
|
||||
**/
|
||||
virtual ~ExprWrapper();
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
|
||||
Expr* expr;
|
||||
|
||||
}; //-- ExprWrapper
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A representation of the XPath NodeSet funtions
|
||||
*/
|
||||
|
@ -270,14 +173,7 @@ public:
|
|||
*/
|
||||
NodeSetFunctionCall(NodeSetFunctions aType);
|
||||
|
||||
/*
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
||||
TX_DECL_EVALUATE;
|
||||
|
||||
private:
|
||||
NodeSetFunctions mType;
|
||||
|
@ -309,14 +205,7 @@ public:
|
|||
**/
|
||||
StringFunctionCall(StringFunctions aType);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
||||
TX_DECL_EVALUATE;
|
||||
|
||||
private:
|
||||
StringFunctions mType;
|
||||
|
@ -343,14 +232,7 @@ public:
|
|||
*/
|
||||
NumberFunctionCall(NumberFunctions aType);
|
||||
|
||||
/*
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
||||
TX_DECL_EVALUATE;
|
||||
|
||||
private:
|
||||
NumberFunctions mType;
|
||||
|
|
|
@ -28,15 +28,17 @@
|
|||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/**
|
||||
* Creates a new LocationStep using the given NodeExpr and Axis Identifier
|
||||
* @param nodeExpr the NodeExpr to use when matching Nodes
|
||||
* @param axisIdentifier the Axis Identifier in which to search for nodes
|
||||
**/
|
||||
LocationStep::LocationStep(NodeExpr* nodeExpr, short axisIdentifier) : PredicateList() {
|
||||
this->nodeExpr = nodeExpr;
|
||||
this->axisIdentifier = axisIdentifier;
|
||||
LocationStep::LocationStep(txNodeTest* aNodeTest,
|
||||
LocationStepType aAxisIdentifier)
|
||||
: mNodeTest(aNodeTest), mAxisIdentifier(aAxisIdentifier)
|
||||
{
|
||||
} //-- LocationStep
|
||||
|
||||
/**
|
||||
|
@ -45,7 +47,7 @@ LocationStep::LocationStep(NodeExpr* nodeExpr, short axisIdentifier) : Predicate
|
|||
* The NodeExpr will be deleted
|
||||
**/
|
||||
LocationStep::~LocationStep() {
|
||||
delete nodeExpr;
|
||||
delete mNodeTest;
|
||||
} //-- ~LocationStep
|
||||
|
||||
//-----------------------------/
|
||||
|
@ -60,23 +62,25 @@ LocationStep::~LocationStep() {
|
|||
* @return the result of the evaluation
|
||||
* @see Expr
|
||||
**/
|
||||
ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||
ExprResult* LocationStep::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(aContext, "internal error");
|
||||
|
||||
NodeSet* nodes = new NodeSet();
|
||||
if (!context || !nodeExpr || !nodes)
|
||||
return nodes;
|
||||
if (!nodes)
|
||||
return 0;
|
||||
|
||||
MBool reverse = MB_FALSE;
|
||||
|
||||
Node* node = context;
|
||||
switch (axisIdentifier) {
|
||||
Node* node = aContext->getContextNode();
|
||||
switch (mAxisIdentifier) {
|
||||
case ANCESTOR_AXIS :
|
||||
node = context->getXPathParent();
|
||||
node = node->getXPathParent();
|
||||
//-- do not break here
|
||||
case ANCESTOR_OR_SELF_AXIS :
|
||||
reverse = MB_TRUE;
|
||||
while (node) {
|
||||
if (nodeExpr->matches(node, context, cs)) {
|
||||
if (mNodeTest->matches(node, aContext)) {
|
||||
nodes->append(node);
|
||||
}
|
||||
node = node->getXPathParent();
|
||||
|
@ -84,28 +88,28 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
|||
break;
|
||||
case ATTRIBUTE_AXIS :
|
||||
{
|
||||
NamedNodeMap* atts = context->getAttributes();
|
||||
NamedNodeMap* atts = node->getAttributes();
|
||||
if (atts) {
|
||||
for (PRUint32 i = 0; i < atts->getLength(); i++) {
|
||||
Node* attr = atts->item(i);
|
||||
if (nodeExpr->matches(attr, context, cs))
|
||||
if (mNodeTest->matches(attr, aContext))
|
||||
nodes->append(attr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DESCENDANT_OR_SELF_AXIS :
|
||||
if (nodeExpr->matches(context, context, cs))
|
||||
nodes->append(context);
|
||||
if (mNodeTest->matches(node, aContext))
|
||||
nodes->append(node);
|
||||
//-- do not break here
|
||||
case DESCENDANT_AXIS :
|
||||
fromDescendants(context, cs, nodes);
|
||||
fromDescendants(node, aContext, nodes);
|
||||
break;
|
||||
case FOLLOWING_AXIS :
|
||||
{
|
||||
if ( node->getNodeType() == Node::ATTRIBUTE_NODE) {
|
||||
node = node->getXPathParent();
|
||||
fromDescendants(node, cs, nodes);
|
||||
fromDescendants(node, aContext, nodes);
|
||||
}
|
||||
while (node && !node->getNextSibling()) {
|
||||
node = node->getXPathParent();
|
||||
|
@ -113,11 +117,11 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
|||
while (node) {
|
||||
node = node->getNextSibling();
|
||||
|
||||
if (nodeExpr->matches(node, context, cs))
|
||||
if (mNodeTest->matches(node, aContext))
|
||||
nodes->append(node);
|
||||
|
||||
if (node->hasChildNodes())
|
||||
fromDescendants(node, cs, nodes);
|
||||
fromDescendants(node, aContext, nodes);
|
||||
|
||||
while (node && !node->getNextSibling()) {
|
||||
node = node->getParentNode();
|
||||
|
@ -126,9 +130,9 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
|||
break;
|
||||
}
|
||||
case FOLLOWING_SIBLING_AXIS :
|
||||
node = context->getNextSibling();
|
||||
node = node->getNextSibling();
|
||||
while (node) {
|
||||
if (nodeExpr->matches(node, context, cs))
|
||||
if (mNodeTest->matches(node, aContext))
|
||||
nodes->append(node);
|
||||
node = node->getNextSibling();
|
||||
}
|
||||
|
@ -141,8 +145,8 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
|||
break;
|
||||
case PARENT_AXIS :
|
||||
{
|
||||
Node* parent = context->getXPathParent();
|
||||
if ( nodeExpr->matches(parent, context, cs) )
|
||||
Node* parent = node->getXPathParent();
|
||||
if (mNodeTest->matches(parent, aContext))
|
||||
nodes->append(parent);
|
||||
break;
|
||||
}
|
||||
|
@ -155,9 +159,9 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
|||
node = node->getPreviousSibling();
|
||||
|
||||
if (node->hasChildNodes())
|
||||
fromDescendantsRev(node, cs, nodes);
|
||||
fromDescendantsRev(node, aContext, nodes);
|
||||
|
||||
if (nodeExpr->matches(node, context, cs))
|
||||
if (mNodeTest->matches(node, aContext))
|
||||
nodes->append(node);
|
||||
|
||||
while (node && !node->getPreviousSibling()) {
|
||||
|
@ -167,56 +171,48 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
|||
break;
|
||||
case PRECEDING_SIBLING_AXIS:
|
||||
reverse = MB_TRUE;
|
||||
node = context->getPreviousSibling();
|
||||
node = node->getPreviousSibling();
|
||||
while (node) {
|
||||
if (nodeExpr->matches(node, context, cs))
|
||||
if (mNodeTest->matches(node, aContext))
|
||||
nodes->append(node);
|
||||
node = node->getPreviousSibling();
|
||||
}
|
||||
break;
|
||||
case SELF_AXIS :
|
||||
if (nodeExpr->matches(context, context, cs))
|
||||
nodes->append(context);
|
||||
if (mNodeTest->matches(node, aContext))
|
||||
nodes->append(node);
|
||||
break;
|
||||
default: //-- Children Axis
|
||||
{
|
||||
Node* tmpNode = context->getFirstChild();
|
||||
while (tmpNode) {
|
||||
if (nodeExpr->matches(tmpNode, context, cs))
|
||||
nodes->append(tmpNode);
|
||||
tmpNode = tmpNode->getNextSibling();
|
||||
node = node->getFirstChild();
|
||||
while (node) {
|
||||
if (mNodeTest->matches(node, aContext))
|
||||
nodes->append(node);
|
||||
node = node->getNextSibling();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} //-- switch
|
||||
|
||||
//-- apply predicates
|
||||
evaluatePredicates(nodes, cs);
|
||||
if (!isEmpty())
|
||||
evaluatePredicates(nodes, aContext);
|
||||
|
||||
if (reverse)
|
||||
nodes->reverse();
|
||||
|
||||
return nodes;
|
||||
} //-- evaluate
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double LocationStep::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
if (isEmpty())
|
||||
return nodeExpr->getDefaultPriority(node, context, cs);
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
void LocationStep::fromDescendants(Node* node, txIMatchContext* cs,
|
||||
NodeSet* nodes)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
|
||||
void LocationStep::fromDescendants(Node* context, ContextState* cs, NodeSet* nodes) {
|
||||
|
||||
if ( !context || !nodeExpr ) return;
|
||||
|
||||
Node* child = context->getFirstChild();
|
||||
Node* child = node->getFirstChild();
|
||||
while (child) {
|
||||
if (nodeExpr->matches(child, context, cs))
|
||||
if (mNodeTest->matches(child, cs))
|
||||
nodes->append(child);
|
||||
//-- check childs descendants
|
||||
if (child->hasChildNodes())
|
||||
|
@ -227,17 +223,19 @@ void LocationStep::fromDescendants(Node* context, ContextState* cs, NodeSet* nod
|
|||
|
||||
} //-- fromDescendants
|
||||
|
||||
void LocationStep::fromDescendantsRev(Node* context, ContextState* cs, NodeSet* nodes) {
|
||||
void LocationStep::fromDescendantsRev(Node* node, txIMatchContext* cs,
|
||||
NodeSet* nodes)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
if ( !context || !nodeExpr ) return;
|
||||
|
||||
Node* child = context->getLastChild();
|
||||
Node* child = node->getLastChild();
|
||||
while (child) {
|
||||
//-- check childs descendants
|
||||
if (child->hasChildNodes())
|
||||
fromDescendantsRev(child, cs, nodes);
|
||||
|
||||
if (nodeExpr->matches(child, context, cs))
|
||||
if (mNodeTest->matches(child, cs))
|
||||
nodes->append(child);
|
||||
|
||||
child = child->getPreviousSibling();
|
||||
|
@ -245,40 +243,13 @@ void LocationStep::fromDescendantsRev(Node* context, ContextState* cs, NodeSet*
|
|||
|
||||
} //-- fromDescendantsRev
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool LocationStep::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
if (!nodeExpr || !node)
|
||||
return MB_FALSE;
|
||||
|
||||
if (!nodeExpr->matches(node, context, cs))
|
||||
return MB_FALSE;
|
||||
|
||||
MBool result = MB_TRUE;
|
||||
if (!isEmpty()) {
|
||||
NodeSet* nodes = (NodeSet*)evaluate(node->getXPathParent(),cs);
|
||||
result = nodes->contains(node);
|
||||
delete nodes;
|
||||
}
|
||||
else if (axisIdentifier == CHILD_AXIS ) {
|
||||
if (!node->getParentNode())
|
||||
result = MB_FALSE;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} //-- matches
|
||||
|
||||
/**
|
||||
* Creates a String representation of this Expr
|
||||
* @param str the destination String to append to
|
||||
* @see Expr
|
||||
**/
|
||||
void LocationStep::toString(String& str) {
|
||||
switch (axisIdentifier) {
|
||||
switch (mAxisIdentifier) {
|
||||
case ANCESTOR_AXIS :
|
||||
str.append("ancestor::");
|
||||
break;
|
||||
|
@ -318,8 +289,9 @@ void LocationStep::toString(String& str) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if ( nodeExpr ) nodeExpr->toString(str);
|
||||
else str.append("null");
|
||||
PredicateList::toString(str);
|
||||
} //-- toString
|
||||
NS_ASSERTION(mNodeTest, "mNodeTest is null, that's verboten");
|
||||
mNodeTest->toString(str);
|
||||
|
||||
PredicateList::toString(str);
|
||||
} // toString
|
||||
|
||||
|
|
|
@ -40,19 +40,13 @@ REQUIRES = string \
|
|||
endif
|
||||
|
||||
CPPSRCS = AdditiveExpr.cpp \
|
||||
AttributeExpr.cpp \
|
||||
AttributeValueTemplate.cpp \
|
||||
BasicNodeExpr.cpp \
|
||||
BooleanExpr.cpp \
|
||||
BooleanFunctionCall.cpp \
|
||||
BooleanResult.cpp \
|
||||
ElementExpr.cpp \
|
||||
ErrorFunctionCall.cpp \
|
||||
Expr.cpp \
|
||||
ExprLexer.cpp \
|
||||
ExprLexerChars.cpp \
|
||||
ExprParser.cpp \
|
||||
ExtensionFunctionCall.cpp \
|
||||
FilterExpr.cpp \
|
||||
FunctionCall.cpp \
|
||||
LocationStep.cpp \
|
||||
|
@ -69,7 +63,10 @@ CPPSRCS = AdditiveExpr.cpp \
|
|||
StringExpr.cpp \
|
||||
StringFunctionCall.cpp \
|
||||
StringResult.cpp \
|
||||
TextExpr.cpp \
|
||||
txNameTest.cpp \
|
||||
txNodeTypeTest.cpp \
|
||||
txForwardContext.cpp \
|
||||
txNodeSetContext.cpp \
|
||||
UnionExpr.cpp \
|
||||
UnaryExpr.cpp \
|
||||
VariableRefExpr.cpp \
|
||||
|
@ -87,6 +84,7 @@ include $(topsrcdir)/config/rules.mk
|
|||
INCLUDES += -I$(srcdir) -I$(srcdir)/../base \
|
||||
-I$(srcdir)/../xml -I$(srcdir)/../xml/dom \
|
||||
-I$(srcdir)/../xslt -I$(srcdir)/../xslt/util \
|
||||
-I$(srcdir)/../xslt/functions
|
||||
-I$(srcdir)/../xslt/functions \
|
||||
-I$(srcdir)
|
||||
|
||||
libs:: $(OBJS)
|
||||
|
|
|
@ -59,21 +59,20 @@ MultiplicativeExpr::~MultiplicativeExpr() {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* MultiplicativeExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
|
||||
ExprResult* MultiplicativeExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
double rightDbl = Double::NaN;
|
||||
ExprResult* exprRes = 0;
|
||||
|
||||
if ( rightExpr ) {
|
||||
exprRes = rightExpr->evaluate(context, cs);
|
||||
exprRes = rightExpr->evaluate(aContext);
|
||||
if ( exprRes ) rightDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
double leftDbl = Double::NaN;
|
||||
if ( leftExpr ) {
|
||||
exprRes = leftExpr->evaluate(context, cs);
|
||||
exprRes = leftExpr->evaluate(aContext);
|
||||
if ( exprRes ) leftDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "XMLDOMUtils.h"
|
||||
#include "Tokenizer.h"
|
||||
#include "txAtom.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/*
|
||||
* Creates a NodeSetFunctionCall of the given type
|
||||
|
@ -75,16 +76,16 @@ NodeSetFunctionCall::NodeSetFunctionCall(NodeSetFunctions aType)
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||
ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) {
|
||||
ListIterator iter(¶ms);
|
||||
switch (mType) {
|
||||
case COUNT:
|
||||
{
|
||||
if (!requireParams(1, 1, aCs))
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* nodes;
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext);
|
||||
if (!nodes)
|
||||
return new StringResult("error");
|
||||
|
||||
|
@ -94,11 +95,11 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
|||
}
|
||||
case ID:
|
||||
{
|
||||
if (!requireParams(1, 1, aCs))
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
ExprResult* exprResult;
|
||||
exprResult = ((Expr*)iter.next())->evaluate(aContext, aCs);
|
||||
exprResult = ((Expr*)iter.next())->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return new StringResult("error");
|
||||
|
||||
|
@ -108,11 +109,12 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Document* contextDoc;
|
||||
if (aContext->getNodeType() == Node::DOCUMENT_NODE)
|
||||
contextDoc = (Document*)aContext;
|
||||
Document* contextDoc = 0;
|
||||
Node* contextNode = aContext->getContextNode();
|
||||
if (contextNode->getNodeType() == Node::DOCUMENT_NODE)
|
||||
contextDoc = (Document*)contextNode;
|
||||
else
|
||||
contextDoc = aContext->getOwnerDocument();
|
||||
contextDoc = contextNode->getOwnerDocument();
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* nodes = (NodeSet*)exprResult;
|
||||
|
@ -123,7 +125,9 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
|||
txTokenizer tokenizer(idList);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
tokenizer.nextToken(id);
|
||||
resultSet->add(contextDoc->getElementById(id));
|
||||
Node* idNode = contextDoc->getElementById(id);
|
||||
if (idNode)
|
||||
resultSet->add(idNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +137,9 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
|||
txTokenizer tokenizer(idList);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
tokenizer.nextToken(id);
|
||||
resultSet->add(contextDoc->getElementById(id));
|
||||
Node* idNode = contextDoc->getElementById(id);
|
||||
if (idNode)
|
||||
resultSet->add(idNode);
|
||||
}
|
||||
}
|
||||
delete exprResult;
|
||||
|
@ -142,30 +148,23 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
|||
}
|
||||
case LAST:
|
||||
{
|
||||
if (!requireParams(0, 0, aCs))
|
||||
if (!requireParams(0, 0, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* contextNodeSet = (NodeSet*)aCs->getNodeSetStack()->peek();
|
||||
if (!contextNodeSet) {
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
return new NumberResult(contextNodeSet->size());
|
||||
return new NumberResult(aContext->size());
|
||||
}
|
||||
case LOCAL_NAME:
|
||||
case NAME:
|
||||
case NAMESPACE_URI:
|
||||
{
|
||||
if (!requireParams(0, 1, aCs))
|
||||
if (!requireParams(0, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
Node* node = 0;
|
||||
// Check for optional arg
|
||||
if (iter.hasNext()) {
|
||||
NodeSet* nodes;
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext);
|
||||
if (!nodes)
|
||||
return new StringResult("error");
|
||||
|
||||
|
@ -177,7 +176,7 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
|||
delete nodes;
|
||||
}
|
||||
else {
|
||||
node = aContext;
|
||||
node = aContext->getContextNode();
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
|
@ -219,21 +218,14 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
|||
}
|
||||
case POSITION:
|
||||
{
|
||||
if (!requireParams(0, 0, aCs))
|
||||
if (!requireParams(0, 0, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* contextNodeSet = (NodeSet*)aCs->getNodeSetStack()->peek();
|
||||
if (!contextNodeSet) {
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
return new NumberResult(contextNodeSet->indexOf(aContext) + 1);
|
||||
return new NumberResult(aContext->position());
|
||||
}
|
||||
}
|
||||
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ NumberExpr::NumberExpr(double dbl) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* NumberExpr::evaluate(Node* context, ContextState* cs) {
|
||||
ExprResult* NumberExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
return new NumberResult(_value);
|
||||
} //-- evaluate
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "FunctionLib.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include <math.h>
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/*
|
||||
* Creates a NumberFunctionCall of the given type
|
||||
|
@ -68,23 +69,23 @@ NumberFunctionCall::NumberFunctionCall(NumberFunctions aType) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||
ExprResult* NumberFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ListIterator iter(¶ms);
|
||||
|
||||
if (mType == NUMBER) {
|
||||
if (!requireParams(0, 1, aCs))
|
||||
if (!requireParams(0, 1, aContext))
|
||||
return new StringResult("error");
|
||||
}
|
||||
else {
|
||||
if (!requireParams(1, 1, aCs))
|
||||
if (!requireParams(1, 1, aContext))
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case CEILING:
|
||||
{
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
||||
return new NumberResult(dbl);
|
||||
|
||||
|
@ -95,7 +96,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case FLOOR:
|
||||
{
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||
if (Double::isNaN(dbl) ||
|
||||
Double::isInfinite(dbl) ||
|
||||
(dbl == 0 && Double::isNeg(dbl)))
|
||||
|
@ -105,7 +106,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case ROUND:
|
||||
{
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
||||
return new NumberResult(dbl);
|
||||
|
||||
|
@ -117,7 +118,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
case SUM:
|
||||
{
|
||||
NodeSet* nodes;
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext);
|
||||
|
||||
if (!nodes)
|
||||
return new StringResult("error");
|
||||
|
@ -137,16 +138,16 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
{
|
||||
if (iter.hasNext()) {
|
||||
return new NumberResult(
|
||||
evaluateToNumber((Expr*)iter.next(), aContext, aCs));
|
||||
evaluateToNumber((Expr*)iter.next(), aContext));
|
||||
}
|
||||
|
||||
String resultStr;
|
||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
||||
XMLDOMUtils::getNodeValue(aContext->getContextNode(), resultStr);
|
||||
return new NumberResult(Double::toDouble(resultStr));
|
||||
}
|
||||
}
|
||||
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
|
|
@ -33,11 +33,17 @@
|
|||
|
||||
#include "Expr.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "txNodeSetContext.h"
|
||||
#include "txSingleNodeContext.h"
|
||||
|
||||
//------------/
|
||||
//- PathExpr -/
|
||||
//------------/
|
||||
|
||||
const String PathExpr::RTF_INVALID_OP =
|
||||
"Result tree fragments don't allow location steps";
|
||||
const String PathExpr::NODESET_EXPECTED =
|
||||
"Filter expression must evaluate to a NodeSet";
|
||||
|
||||
/**
|
||||
* Creates a new PathExpr
|
||||
|
@ -94,12 +100,14 @@ void PathExpr::addExpr(Expr* expr, PathOperator pathOp)
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* PathExpr::evaluate(Node* context, ContextState* cs)
|
||||
ExprResult* PathExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
if (!context || !expressions.getLength())
|
||||
if (!aContext || (expressions.getLength() == 0)) {
|
||||
NS_ASSERTION(0, "internal error");
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
NodeSet* nodes = new NodeSet(context);
|
||||
NodeSet* nodes = new NodeSet(aContext->getContextNode());
|
||||
if (!nodes) {
|
||||
// XXX ErrorReport: out of memory
|
||||
NS_ASSERTION(0, "out of memory");
|
||||
|
@ -111,16 +119,18 @@ ExprResult* PathExpr::evaluate(Node* context, ContextState* cs)
|
|||
|
||||
while ((pxi = (PathExprItem*)iter.next())) {
|
||||
NodeSet* tmpNodes = 0;
|
||||
for (int i = 0; i < nodes->size(); i++) {
|
||||
Node* node = nodes->get(i);
|
||||
txNodeSetContext eContext(nodes, aContext);
|
||||
while (eContext.hasNext()) {
|
||||
eContext.next();
|
||||
Node* node = eContext.getContextNode();
|
||||
|
||||
NodeSet* resNodes;
|
||||
if (pxi->pathOp == DESCENDANT_OP) {
|
||||
resNodes = new NodeSet;
|
||||
evalDescendants(pxi->expr, node, cs, resNodes);
|
||||
evalDescendants(pxi->expr, node, &eContext, resNodes);
|
||||
}
|
||||
else {
|
||||
ExprResult *res = pxi->expr->evaluate(node, cs);
|
||||
ExprResult *res = pxi->expr->evaluate(&eContext);
|
||||
if (!res || (res->getResultType() != ExprResult::NODESET)) {
|
||||
//XXX ErrorReport: report nonnodeset error
|
||||
delete res;
|
||||
|
@ -147,12 +157,13 @@ ExprResult* PathExpr::evaluate(Node* context, ContextState* cs)
|
|||
/**
|
||||
* Selects from the descendants of the context node
|
||||
* all nodes that match the Expr
|
||||
* -- this will be moving to a Utility class
|
||||
**/
|
||||
void PathExpr::evalDescendants (Expr* expr, Node* context,
|
||||
ContextState* cs, NodeSet* resNodes)
|
||||
void PathExpr::evalDescendants (Expr* aStep, Node* aNode,
|
||||
txIMatchContext* aContext,
|
||||
NodeSet* resNodes)
|
||||
{
|
||||
ExprResult *res = expr->evaluate(context, cs);
|
||||
txSingleNodeContext eContext(aNode, aContext);
|
||||
ExprResult *res = aStep->evaluate(&eContext);
|
||||
if (!res || (res->getResultType() != ExprResult::NODESET)) {
|
||||
//XXX ErrorReport: report nonnodeset error
|
||||
}
|
||||
|
@ -161,107 +172,19 @@ void PathExpr::evalDescendants (Expr* expr, Node* context,
|
|||
}
|
||||
delete res;
|
||||
|
||||
MBool filterWS = cs->isStripSpaceAllowed(context);
|
||||
MBool filterWS = aContext->isStripSpaceAllowed(aNode);
|
||||
|
||||
Node* child = context->getFirstChild();
|
||||
Node* child = aNode->getFirstChild();
|
||||
while (child) {
|
||||
if (!(filterWS &&
|
||||
(child->getNodeType() == Node::TEXT_NODE ||
|
||||
child->getNodeType() == Node::CDATA_SECTION_NODE) &&
|
||||
XMLUtils::shouldStripTextnode(child->getNodeValue())))
|
||||
evalDescendants(expr, child, cs, resNodes);
|
||||
evalDescendants(aStep, child, aContext, resNodes);
|
||||
child = child->getNextSibling();
|
||||
}
|
||||
} //-- evalDescendants
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double PathExpr::getDefaultPriority(Node* node, Node* context,
|
||||
ContextState* cs)
|
||||
{
|
||||
int size = expressions.getLength();
|
||||
if (size > 1)
|
||||
return 0.5;
|
||||
|
||||
return ((PathExprItem*)expressions.get(0))->
|
||||
expr->getDefaultPriority(node, context, cs);
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool PathExpr::matches(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
/*
|
||||
* The idea is to split up a path into blocks separated by descendant
|
||||
* operators. For example "foo/bar//baz/bop//ying/yang" is split up into
|
||||
* three blocks. The "ying/yang" block is handled by the first while-loop
|
||||
* and the "foo/bar" and "baz/bop" blocks are handled by the second
|
||||
* while-loop.
|
||||
* A block is considered matched when we find a list of ancestors that
|
||||
* match the block. If there are more than one list of ancestors that
|
||||
* match a block we only need to find the one furthermost down in the
|
||||
* tree.
|
||||
*/
|
||||
|
||||
if (!node || (expressions.getLength() == 0))
|
||||
return MB_FALSE;
|
||||
|
||||
ListIterator iter(&expressions);
|
||||
iter.resetToEnd();
|
||||
|
||||
PathExprItem* pxi;
|
||||
PathOperator pathOp = RELATIVE_OP;
|
||||
|
||||
while (pathOp == RELATIVE_OP) {
|
||||
|
||||
pxi = (PathExprItem*)iter.previous();
|
||||
if (!pxi)
|
||||
return MB_TRUE; // We've stepped through the entire list
|
||||
|
||||
if (!node || !pxi->expr->matches(node, 0, cs))
|
||||
return MB_FALSE;
|
||||
|
||||
node = node->getXPathParent();
|
||||
pathOp = pxi->pathOp;
|
||||
}
|
||||
|
||||
// We have at least one DESCENDANT_OP
|
||||
|
||||
Node* blockStart = node;
|
||||
ListIterator blockIter(iter);
|
||||
|
||||
while ((pxi = (PathExprItem*)iter.previous())) {
|
||||
|
||||
if (!node)
|
||||
return MB_FALSE; // There are more steps in the current block
|
||||
// then ancestors of the tested node
|
||||
|
||||
if (!pxi->expr->matches(node, 0, cs)) {
|
||||
// Didn't match. We restart at beginning of block using a new
|
||||
// start node
|
||||
iter = blockIter;
|
||||
blockStart = blockStart->getXPathParent();
|
||||
node = blockStart;
|
||||
}
|
||||
else {
|
||||
node = node->getXPathParent();
|
||||
if (pxi->pathOp == DESCENDANT_OP) {
|
||||
// We've matched an entire block. Set new start iter and start node
|
||||
blockIter = iter;
|
||||
blockStart = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MB_TRUE;
|
||||
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txNodeSetContext.h"
|
||||
|
||||
/*
|
||||
* Represents an ordered list of Predicates,
|
||||
|
@ -56,38 +57,39 @@ void PredicateList::add(Expr* expr)
|
|||
predicates.add(expr);
|
||||
} // add
|
||||
|
||||
void PredicateList::evaluatePredicates(NodeSet* nodes, ContextState* cs)
|
||||
void PredicateList::evaluatePredicates(NodeSet* nodes,
|
||||
txIMatchContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(nodes, "called evaluatePredicates with NULL NodeSet");
|
||||
if (!nodes)
|
||||
return;
|
||||
|
||||
cs->getNodeSetStack()->push(nodes);
|
||||
NodeSet newNodes;
|
||||
txListIterator iter(&predicates);
|
||||
while (iter.hasNext()) {
|
||||
while (iter.hasNext() && !nodes->isEmpty()) {
|
||||
Expr* expr = (Expr*)iter.next();
|
||||
txNodeSetContext predContext(nodes, aContext);
|
||||
/*
|
||||
* add nodes to newNodes that match the expression
|
||||
* or, if the result is a number, add the node with the right
|
||||
* position
|
||||
*/
|
||||
newNodes.clear();
|
||||
int nIdx;
|
||||
for (nIdx = 0; nIdx < nodes->size(); nIdx++) {
|
||||
Node* node = nodes->get(nIdx);
|
||||
ExprResult* exprResult = expr->evaluate(node, cs);
|
||||
while (predContext.hasNext()) {
|
||||
predContext.next();
|
||||
ExprResult* exprResult = expr->evaluate(&predContext);
|
||||
if (!exprResult)
|
||||
break;
|
||||
switch(exprResult->getResultType()) {
|
||||
case ExprResult::NUMBER :
|
||||
// handle default, [position() == numberValue()]
|
||||
if ((double)(nIdx+1) == exprResult->numberValue())
|
||||
newNodes.append(node);
|
||||
if ((double)predContext.position() ==
|
||||
exprResult->numberValue())
|
||||
newNodes.append(predContext.getContextNode());
|
||||
break;
|
||||
default:
|
||||
if (exprResult->booleanValue())
|
||||
newNodes.append(node);
|
||||
newNodes.append(predContext.getContextNode());
|
||||
break;
|
||||
}
|
||||
delete exprResult;
|
||||
|
@ -96,7 +98,6 @@ void PredicateList::evaluatePredicates(NodeSet* nodes, ContextState* cs)
|
|||
nodes->clear();
|
||||
nodes->append(&newNodes);
|
||||
}
|
||||
cs->getNodeSetStack()->pop();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -204,16 +204,19 @@ MBool RelationalExpr::compareResults(ExprResult* left, ExprResult* right) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* RelationalExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
ExprResult* RelationalExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
//-- get result of left expression
|
||||
ExprResult* lResult = 0;
|
||||
if ( leftExpr ) lResult = leftExpr->evaluate(context, cs);
|
||||
else return new BooleanResult();
|
||||
if (leftExpr)
|
||||
lResult = leftExpr->evaluate(aContext);
|
||||
else
|
||||
return new BooleanResult();
|
||||
|
||||
//-- get result of right expr
|
||||
ExprResult* rResult = 0;
|
||||
if ( rightExpr ) rResult = rightExpr->evaluate(context, cs);
|
||||
if (rightExpr)
|
||||
rResult = rightExpr->evaluate(aContext);
|
||||
else {
|
||||
delete lResult;
|
||||
return new BooleanResult();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/**
|
||||
* Creates a new RootExpr
|
||||
|
@ -40,32 +41,19 @@ RootExpr::RootExpr(MBool aSerialize) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* RootExpr::evaluate(Node* context, ContextState* cs)
|
||||
ExprResult* RootExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
if (!context)
|
||||
return new StringResult("error");
|
||||
Node* context;
|
||||
if (!aContext || !(context = aContext->getContextNode())) {
|
||||
NS_ASSERTION(0, "internal error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (context->getNodeType() != Node::DOCUMENT_NODE)
|
||||
return new NodeSet(context->getOwnerDocument());
|
||||
return new NodeSet(context);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double RootExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this NodeExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool RootExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
return node && (node->getNodeType() == Node::DOCUMENT_NODE);
|
||||
} //-- matches
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
|
|
|
@ -44,7 +44,8 @@ StringExpr::StringExpr(const String& value) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* StringExpr::evaluate(Node* context, ContextState* cs) {
|
||||
ExprResult* StringExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
return new StringResult(value);
|
||||
} //-- evaluate
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "FunctionLib.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
|
@ -76,41 +77,42 @@ StringFunctionCall::StringFunctionCall(StringFunctions aType) : mType(aType)
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||
ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ListIterator iter(¶ms);
|
||||
switch (mType) {
|
||||
case CONCAT:
|
||||
{
|
||||
if (!requireParams(2, aCs))
|
||||
if (!requireParams(2, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String resultStr;
|
||||
while (iter.hasNext()) {
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
||||
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||
}
|
||||
return new StringResult(resultStr);
|
||||
}
|
||||
case CONTAINS:
|
||||
{
|
||||
if (!requireParams(2, 2, aCs))
|
||||
if (!requireParams(2, 2, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||
return new BooleanResult(arg1.indexOf(arg2) >= 0);
|
||||
}
|
||||
case NORMALIZE_SPACE:
|
||||
{
|
||||
if (!requireParams(0, 1, aCs))
|
||||
if (!requireParams(0, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String resultStr;
|
||||
if (iter.hasNext())
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
||||
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||
else
|
||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
||||
XMLDOMUtils::getNodeValue(aContext->getContextNode(),
|
||||
resultStr);
|
||||
|
||||
MBool addSpace = MB_FALSE;
|
||||
MBool first = MB_TRUE;
|
||||
|
@ -136,35 +138,36 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case STARTS_WITH:
|
||||
{
|
||||
if (!requireParams(2, 2, aCs))
|
||||
if (!requireParams(2, 2, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||
return new BooleanResult(arg1.indexOf(arg2) == 0);
|
||||
}
|
||||
case STRING_LENGTH:
|
||||
{
|
||||
if (!requireParams(0, 1, aCs))
|
||||
if (!requireParams(0, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String resultStr;
|
||||
if (iter.hasNext())
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
||||
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||
else
|
||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
||||
XMLDOMUtils::getNodeValue(aContext->getContextNode(),
|
||||
resultStr);
|
||||
return new NumberResult(resultStr.length());
|
||||
}
|
||||
case SUBSTRING:
|
||||
{
|
||||
if (!requireParams(2, 3, aCs))
|
||||
if (!requireParams(2, 3, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String src;
|
||||
double start, end;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, src);
|
||||
start = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
||||
evaluateToString((Expr*)iter.next(), aContext, src);
|
||||
start = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||
|
||||
// check for NaN or +/-Inf
|
||||
if (Double::isNaN(start) ||
|
||||
|
@ -175,8 +178,7 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
start = floor(start + 0.5) - 1;
|
||||
if (iter.hasNext()) {
|
||||
end = start + evaluateToNumber((Expr*)iter.next(),
|
||||
aContext,
|
||||
aCs);
|
||||
aContext);
|
||||
if (Double::isNaN(end) || end < 0)
|
||||
return new StringResult();
|
||||
|
||||
|
@ -201,12 +203,12 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case SUBSTRING_AFTER:
|
||||
{
|
||||
if (!requireParams(2, 2, aCs))
|
||||
if (!requireParams(2, 2, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||
PRInt32 idx = arg1.indexOf(arg2);
|
||||
if (idx >= 0) {
|
||||
PRInt32 len = arg2.length();
|
||||
|
@ -217,12 +219,12 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case SUBSTRING_BEFORE:
|
||||
{
|
||||
if (!requireParams(2, 2, aCs))
|
||||
if (!requireParams(2, 2, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||
PRInt32 idx = arg1.indexOf(arg2);
|
||||
if (idx >= 0) {
|
||||
arg2.clear();
|
||||
|
@ -233,17 +235,17 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case TRANSLATE:
|
||||
{
|
||||
if (!requireParams(3, 3, aCs))
|
||||
if (!requireParams(3, 3, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String src;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, src);
|
||||
evaluateToString((Expr*)iter.next(), aContext, src);
|
||||
if (src.isEmpty())
|
||||
return new StringResult();
|
||||
|
||||
String oldChars, newChars, dest;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, oldChars);
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, newChars);
|
||||
evaluateToString((Expr*)iter.next(), aContext, oldChars);
|
||||
evaluateToString((Expr*)iter.next(), aContext, newChars);
|
||||
PRInt32 i;
|
||||
for (i = 0; i < src.length(); i++) {
|
||||
PRInt32 idx = oldChars.indexOf(src.charAt(i));
|
||||
|
@ -259,19 +261,20 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
}
|
||||
case STRING:
|
||||
{
|
||||
if (!requireParams(0, 1, aCs))
|
||||
if (!requireParams(0, 1, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
String resultStr;
|
||||
if (iter.hasNext())
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
||||
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||
else
|
||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
||||
XMLDOMUtils::getNodeValue(aContext->getContextNode(),
|
||||
resultStr);
|
||||
return new StringResult(resultStr);
|
||||
}
|
||||
}
|
||||
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* TextExpr::evaluate(Node* context, ContextState* cs) {
|
||||
NS_ASSERTION(0, "TextExpr::evaluate called");
|
||||
return 0;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double TextExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
return -0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this NodeExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool TextExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
if (node) {
|
||||
if (node->getNodeType() == Node::TEXT_NODE ||
|
||||
node->getNodeType() == Node::CDATA_SECTION_NODE)
|
||||
return !cs->isStripSpaceAllowed(node);
|
||||
}
|
||||
return MB_FALSE;
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this NodeExpr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this NodeExpr.
|
||||
**/
|
||||
void TextExpr::toString(String& dest) {
|
||||
dest.append("text()");
|
||||
} //-- toString
|
||||
|
|
@ -42,9 +42,9 @@ UnaryExpr::~UnaryExpr()
|
|||
* for evaluation.
|
||||
* @return the result of the evaluation.
|
||||
*/
|
||||
ExprResult* UnaryExpr::evaluate(Node* context, ContextState* cs)
|
||||
ExprResult* UnaryExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ExprResult* exprRes = expr->evaluate(context, cs);
|
||||
ExprResult* exprRes = expr->evaluate(aContext);
|
||||
double value = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
#ifdef HPUX
|
||||
|
|
|
@ -69,21 +69,22 @@ void UnionExpr::addExpr(Expr* expr) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* UnionExpr::evaluate(Node* context, ContextState* cs)
|
||||
ExprResult* UnionExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
NodeSet* nodes = new NodeSet();
|
||||
|
||||
if (!context || expressions.getLength() == 0 || !nodes)
|
||||
if (!aContext || (expressions.getLength() == 0) || !nodes)
|
||||
return nodes;
|
||||
|
||||
txListIterator iter(&expressions);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Expr* expr = (Expr*)iter.next();
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
ExprResult* exprResult = expr->evaluate(aContext);
|
||||
if (!exprResult ||
|
||||
exprResult->getResultType() != ExprResult::NODESET) {
|
||||
delete exprResult;
|
||||
delete nodes;
|
||||
return new StringResult("error");
|
||||
}
|
||||
nodes->add((NodeSet*)exprResult);
|
||||
|
@ -93,45 +94,6 @@ ExprResult* UnionExpr::evaluate(Node* context, ContextState* cs)
|
|||
return nodes;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double UnionExpr::getDefaultPriority(Node* node, Node* context,
|
||||
ContextState* cs)
|
||||
{
|
||||
//-- find highest priority
|
||||
double priority = Double::NEGATIVE_INFINITY;
|
||||
ListIterator iter(&expressions);
|
||||
while (iter.hasNext()) {
|
||||
Expr* expr = (Expr*)iter.next();
|
||||
double tmpPriority = expr->getDefaultPriority(node, context, cs);
|
||||
if (tmpPriority > priority && expr->matches(node, context, cs))
|
||||
priority = tmpPriority;
|
||||
}
|
||||
return priority;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this UnionExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool UnionExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
ListIterator* iter = expressions.iterator();
|
||||
|
||||
while (iter->hasNext()) {
|
||||
Expr* expr = (Expr*)iter->next();
|
||||
if (expr->matches(node, context, cs)) {
|
||||
delete iter;
|
||||
return MB_TRUE;
|
||||
}
|
||||
}
|
||||
delete iter;
|
||||
return MB_FALSE;
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
//-------------------/
|
||||
//- VariableRefExpr -/
|
||||
|
@ -32,9 +34,25 @@
|
|||
/**
|
||||
* Creates a VariableRefExpr with the given variable name
|
||||
**/
|
||||
VariableRefExpr::VariableRefExpr(const String& name) {
|
||||
this->name = name;
|
||||
} //-- VariableRefExpr
|
||||
VariableRefExpr::VariableRefExpr(txAtom* aPrefix, txAtom* aLocalName,
|
||||
PRInt32 aNSID)
|
||||
: mPrefix(aPrefix), mLocalName(aLocalName), mNamespace(aNSID)
|
||||
{
|
||||
NS_ASSERTION(mLocalName, "VariableRefExpr without local name?");
|
||||
if (mPrefix == txXMLAtoms::_empty)
|
||||
mPrefix = 0;
|
||||
TX_IF_ADDREF_ATOM(mPrefix);
|
||||
TX_IF_ADDREF_ATOM(mLocalName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Release the local name atom
|
||||
*/
|
||||
VariableRefExpr::~VariableRefExpr()
|
||||
{
|
||||
TX_IF_RELEASE_ATOM(mPrefix);
|
||||
TX_IF_RELEASE_ATOM(mLocalName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
|
@ -43,9 +61,14 @@ VariableRefExpr::VariableRefExpr(const String& name) {
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* VariableRefExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
ExprResult* exprResult = cs->getVariable(name);
|
||||
ExprResult* VariableRefExpr::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ExprResult* exprResult = 0;
|
||||
nsresult rv = aContext->getVariable(mNamespace, mLocalName, exprResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX report error, undefined variable
|
||||
return 0;
|
||||
}
|
||||
//-- make copy to prevent deletetion
|
||||
//-- I know, I should add a #copy method to ExprResult, I will
|
||||
ExprResult* copyOfResult = 0;
|
||||
|
@ -88,7 +111,16 @@ ExprResult* VariableRefExpr::evaluate(Node* context, ContextState* cs) {
|
|||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void VariableRefExpr::toString(String& str) {
|
||||
str.append('$');
|
||||
str.append(name);
|
||||
void VariableRefExpr::toString(String& aDest)
|
||||
{
|
||||
aDest.append('$');
|
||||
if (mPrefix) {
|
||||
String prefix;
|
||||
TX_GET_ATOM_STRING(mPrefix, prefix);
|
||||
aDest.append(prefix);
|
||||
aDest.append(':');
|
||||
}
|
||||
String lname;
|
||||
TX_GET_ATOM_STRING(mLocalName, lname);
|
||||
aDest.append(lname);
|
||||
} //-- toString
|
||||
|
|
|
@ -37,19 +37,13 @@ DEFINES=$(DEFINES) -DTX_EXE
|
|||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\AdditiveExpr.obj \
|
||||
.\$(OBJDIR)\AttributeExpr.obj \
|
||||
.\$(OBJDIR)\AttributeValueTemplate.obj \
|
||||
.\$(OBJDIR)\BasicNodeExpr.obj \
|
||||
.\$(OBJDIR)\BooleanExpr.obj \
|
||||
.\$(OBJDIR)\BooleanFunctionCall.obj \
|
||||
.\$(OBJDIR)\BooleanResult.obj \
|
||||
.\$(OBJDIR)\ElementExpr.obj \
|
||||
.\$(OBJDIR)\ErrorFunctionCall.obj \
|
||||
.\$(OBJDIR)\Expr.obj \
|
||||
.\$(OBJDIR)\ExprLexer.obj \
|
||||
.\$(OBJDIR)\ExprLexerChars.obj \
|
||||
.\$(OBJDIR)\ExprParser.obj \
|
||||
.\$(OBJDIR)\ExtensionFunctionCall.obj \
|
||||
.\$(OBJDIR)\FilterExpr.obj \
|
||||
.\$(OBJDIR)\FunctionCall.obj \
|
||||
.\$(OBJDIR)\LocationStep.obj \
|
||||
|
@ -66,7 +60,10 @@ CPP_OBJS= \
|
|||
.\$(OBJDIR)\StringExpr.obj \
|
||||
.\$(OBJDIR)\StringFunctionCall.obj \
|
||||
.\$(OBJDIR)\StringResult.obj \
|
||||
.\$(OBJDIR)\TextExpr.obj \
|
||||
.\$(OBJDIR)\txNameTest.obj \
|
||||
.\$(OBJDIR)\txNodeTypeTest.obj \
|
||||
.\$(OBJDIR)\txForwardContext.obj \
|
||||
.\$(OBJDIR)\txNodeSetContext.obj \
|
||||
.\$(OBJDIR)\UnionExpr.obj \
|
||||
.\$(OBJDIR)\UnaryExpr.obj \
|
||||
.\$(OBJDIR)\VariableRefExpr.obj \
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "nsXPathNSResolver.h"
|
||||
#include "nsXPathResult.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "ExprParser.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsXPathEvaluator)
|
||||
NS_IMPL_RELEASE(nsXPathEvaluator)
|
||||
|
@ -69,8 +71,8 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
|||
nsIDOMXPathExpression **aResult)
|
||||
{
|
||||
String expressionString(PromiseFlatString(aExpression).get());
|
||||
// XXX (pvdb) TODO Set the right resolver on the ExprParser
|
||||
Expr* expression = mParser.createExpr(expressionString);
|
||||
ParseContextImpl pContext(aResolver);
|
||||
Expr* expression = ExprParser::createExpr(expressionString, &pContext);
|
||||
if (!expression)
|
||||
return NS_ERROR_DOM_INVALID_EXPRESSION_ERR;
|
||||
|
||||
|
@ -114,3 +116,58 @@ nsXPathEvaluator::Evaluate(const nsAString & aExpression,
|
|||
|
||||
return expression->Evaluate(aContextNode, aType, aInResult, aResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of txIParseContext private to nsXPathEvaluator
|
||||
* ParseContextImpl bases on a nsIDOMXPathNSResolver
|
||||
*/
|
||||
|
||||
static NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
|
||||
|
||||
nsresult nsXPathEvaluator::ParseContextImpl::resolveNamespacePrefix
|
||||
(txAtom* aPrefix, PRInt32& aID)
|
||||
{
|
||||
nsAutoString prefix;
|
||||
if (aPrefix) {
|
||||
aPrefix->ToString(prefix);
|
||||
}
|
||||
nsAutoString ns;
|
||||
nsresult rv = NS_OK;
|
||||
if (mResolver) {
|
||||
mResolver->LookupNamespaceURI(prefix, ns);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
aID = kNameSpaceID_None;
|
||||
if (ns.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!mResolver) {
|
||||
aID = kNameSpaceID_Unknown;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mNSMan) {
|
||||
mNSMan = do_CreateInstance(kNameSpaceManagerCID);
|
||||
if (!mNSMan) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
// get the namespaceID for the URI
|
||||
|
||||
return mNSMan->RegisterNameSpace(ns, aID);
|
||||
}
|
||||
|
||||
nsresult nsXPathEvaluator::ParseContextImpl::resolveFunctionCall(txAtom* aName,
|
||||
PRInt32 aID,
|
||||
FunctionCall*& aFn)
|
||||
{
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
}
|
||||
|
||||
void nsXPathEvaluator::ParseContextImpl::receiveError(const String& aMsg,
|
||||
nsresult aRes)
|
||||
{
|
||||
mLastError = aRes;
|
||||
// forward aMsg to console service?
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
#define nsXPathEvaluator_h__
|
||||
|
||||
#include "nsIDOMXPathEvaluator.h"
|
||||
#include "ExprParser.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
|
||||
/**
|
||||
* A class for evaluating an XPath expression string
|
||||
|
@ -59,7 +60,34 @@ public:
|
|||
NS_DECL_NSIDOMXPATHEVALUATOR
|
||||
|
||||
private:
|
||||
ExprParser mParser;
|
||||
// txIParseContext implementation
|
||||
class ParseContextImpl : public txIParseContext
|
||||
{
|
||||
public:
|
||||
ParseContextImpl(nsIDOMXPathNSResolver* aResolver)
|
||||
: mResolver(aResolver), mLastError(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
~ParseContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult getError()
|
||||
{
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
nsresult resolveNamespacePrefix(txAtom* aPrefix, PRInt32& aID);
|
||||
nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction);
|
||||
void receiveError(const String& aMsg, nsresult aRes);
|
||||
|
||||
private:
|
||||
nsIDOMXPathNSResolver* mResolver;
|
||||
nsresult mLastError;
|
||||
nsCOMPtr<nsINameSpaceManager> mNSMan;
|
||||
};
|
||||
};
|
||||
|
||||
/* d0a75e02-b5e7-11d5-a7f2-df109fb8a1fc */
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIDOMXPathNamespace.h"
|
||||
#include "nsXPathResult.h"
|
||||
#include "ProcessorState.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsXPathExpression)
|
||||
NS_IMPL_RELEASE(nsXPathExpression)
|
||||
|
@ -112,8 +111,8 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
|
|||
Document document(ownerDOMDocument);
|
||||
Node* node = document.createWrapper(aContextNode);
|
||||
|
||||
ProcessorState processorState;
|
||||
ExprResult* exprResult = mExpression->evaluate(node, &processorState);
|
||||
EvalContextImpl eContext(node);
|
||||
ExprResult* exprResult = mExpression->evaluate(&eContext);
|
||||
NS_ENSURE_TRUE(exprResult, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
PRUint16 resultType = aType;
|
||||
|
@ -152,3 +151,43 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
|
|||
|
||||
return CallQueryInterface(xpathResult, aResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of the txIEvalContext private to nsXPathExpression
|
||||
* EvalContextImpl bases on only one context node and no variables
|
||||
*/
|
||||
|
||||
nsresult nsXPathExpression::EvalContextImpl::getVariable(PRInt32 aNamespace,
|
||||
txAtom* aLName,
|
||||
ExprResult*& aResult)
|
||||
{
|
||||
aResult = 0;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
MBool nsXPathExpression::EvalContextImpl::isStripSpaceAllowed(Node* aNode)
|
||||
{
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
void nsXPathExpression::EvalContextImpl::receiveError(const String& aMsg,
|
||||
nsresult aRes)
|
||||
{
|
||||
mLastError = aRes;
|
||||
// forward aMsg to console service?
|
||||
}
|
||||
|
||||
Node* nsXPathExpression::EvalContextImpl::getContextNode()
|
||||
{
|
||||
return mNode;
|
||||
}
|
||||
|
||||
PRUint32 nsXPathExpression::EvalContextImpl::size()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
PRUint32 nsXPathExpression::EvalContextImpl::position()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#define nsXPathExpression_h__
|
||||
|
||||
#include "nsIDOMXPathExpression.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
class Expr;
|
||||
|
||||
|
@ -61,6 +62,29 @@ public:
|
|||
|
||||
private:
|
||||
Expr* mExpression;
|
||||
|
||||
class EvalContextImpl : public txIEvalContext
|
||||
{
|
||||
public:
|
||||
EvalContextImpl(Node* aContextNode)
|
||||
:mNode(aContextNode), mLastError(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
~EvalContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult getError()
|
||||
{
|
||||
return mLastError;
|
||||
}
|
||||
|
||||
TX_DECL_EVAL_CONTEXT;
|
||||
private:
|
||||
Node* mNode;
|
||||
nsresult mLastError;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txForwardContext.h"
|
||||
|
||||
Node* txForwardContext::getContextNode()
|
||||
{
|
||||
return mContext;
|
||||
}
|
||||
|
||||
PRUint32 txForwardContext::size()
|
||||
{
|
||||
return (PRUint32)mContextSet->size();
|
||||
}
|
||||
|
||||
PRUint32 txForwardContext::position()
|
||||
{
|
||||
int pos = mContextSet->indexOf(mContext);
|
||||
NS_ASSERTION(pos >= 0, "Context is not member of context node list.");
|
||||
return (PRUint32)(pos+1);
|
||||
}
|
||||
|
||||
nsresult txForwardContext::getVariable(PRInt32 aNamespace, txAtom* aLName,
|
||||
ExprResult*& aResult)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->getVariable(aNamespace, aLName, aResult);
|
||||
}
|
||||
|
||||
MBool txForwardContext::isStripSpaceAllowed(Node* aNode)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->isStripSpaceAllowed(aNode);
|
||||
}
|
||||
|
||||
void txForwardContext::receiveError(const String& aMsg, nsresult aRes)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
#ifdef DEBUG
|
||||
String error("forwarded error: ");
|
||||
error.append(aMsg);
|
||||
mInner->receiveError(error, aRes);
|
||||
#else
|
||||
mInner->receiveError(aMsg, aRes);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __TX_XPATH_CONTEXT
|
||||
#define __TX_XPATH_CONTEXT
|
||||
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
class txForwardContext : public txIEvalContext
|
||||
{
|
||||
public:
|
||||
txForwardContext(txIMatchContext* aContext, Node* aContextNode,
|
||||
NodeSet* aContextNodeSet) : mContext(aContextNode),
|
||||
mContextSet(aContextNodeSet),
|
||||
mInner(aContext)
|
||||
{}
|
||||
~txForwardContext()
|
||||
{}
|
||||
|
||||
TX_DECL_EVAL_CONTEXT;
|
||||
|
||||
private:
|
||||
Node* mContext;
|
||||
NodeSet* mContextSet;
|
||||
txIMatchContext* mInner;
|
||||
};
|
||||
|
||||
#endif // __TX_XPATH_CONTEXT
|
|
@ -0,0 +1,150 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __TX_I_XPATH_CONTEXT
|
||||
#define __TX_I_XPATH_CONTEXT
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txError.h"
|
||||
|
||||
/*
|
||||
* txIParseContext
|
||||
*
|
||||
* This interface describes the context needed to create
|
||||
* XPath Expressions and XSLT Patters.
|
||||
* (not completely though. key() requires the ProcessorState, which is
|
||||
* not part of this interface.)
|
||||
*/
|
||||
|
||||
class txIParseContext
|
||||
{
|
||||
public:
|
||||
virtual ~txIParseContext()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a namespaceID for a given prefix.
|
||||
*/
|
||||
virtual nsresult resolveNamespacePrefix(txAtom* aPrefix, PRInt32& aID) = 0;
|
||||
|
||||
/*
|
||||
* Create a FunctionCall, needed for extension function calls and
|
||||
* XSLT. XPath function calls are resolved by the Parser.
|
||||
*/
|
||||
virtual nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction) = 0;
|
||||
|
||||
/*
|
||||
* Callback to be used by the Parser if errors are detected.
|
||||
*/
|
||||
virtual void receiveError(const String& aMsg, nsresult aRes) = 0;
|
||||
};
|
||||
|
||||
/*
|
||||
* txIMatchContext
|
||||
*
|
||||
* Interface used for matching XSLT Patters.
|
||||
* This is the part of txIEvalContext (see below), that is independent
|
||||
* of the context node when evaluating a XPath expression, too.
|
||||
* When evaluating a XPath expression, |txIMatchContext|s are used
|
||||
* to transport the information from Step to Step.
|
||||
*/
|
||||
class txIMatchContext
|
||||
{
|
||||
public:
|
||||
virtual ~txIMatchContext()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the ExprResult associated with the variable with the
|
||||
* given namespace and local name.
|
||||
*/
|
||||
virtual nsresult getVariable(PRInt32 aNamespace, txAtom* aLName,
|
||||
ExprResult*& aResult) = 0;
|
||||
|
||||
/*
|
||||
* Is whitespace stripping allowed for the given node?
|
||||
* See http://www.w3.org/TR/xslt#strip
|
||||
*/
|
||||
virtual MBool isStripSpaceAllowed(Node* aNode) = 0;
|
||||
|
||||
/*
|
||||
* Callback to be used by the expression/pattern if errors are detected.
|
||||
*/
|
||||
virtual void receiveError(const String& aMsg, nsresult aRes) = 0;
|
||||
};
|
||||
|
||||
#define TX_DECL_MATCH_CONTEXT \
|
||||
nsresult getVariable(PRInt32 aNamespace, txAtom* aLName, \
|
||||
ExprResult*& aResult); \
|
||||
MBool isStripSpaceAllowed(Node* aNode); \
|
||||
void receiveError(const String& aMsg, nsresult aRes)
|
||||
|
||||
class txIEvalContext : public txIMatchContext
|
||||
{
|
||||
public:
|
||||
virtual ~txIEvalContext()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the context node.
|
||||
*/
|
||||
virtual Node* getContextNode() = 0;
|
||||
|
||||
/*
|
||||
* Get the size of the context node set.
|
||||
*/
|
||||
virtual PRUint32 size() = 0;
|
||||
|
||||
/*
|
||||
* Get the position of the context node in the context node set,
|
||||
* starting with 1.
|
||||
*/
|
||||
virtual PRUint32 position() = 0;
|
||||
};
|
||||
|
||||
#define TX_DECL_EVAL_CONTEXT \
|
||||
TX_DECL_MATCH_CONTEXT; \
|
||||
Node* getContextNode(); \
|
||||
PRUint32 size(); \
|
||||
PRUint32 position()
|
||||
|
||||
#endif // __TX_I_XPATH_CONTEXT
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
txNameTest::txNameTest(txAtom* aPrefix, txAtom* aLocalName, PRInt32 aNSID,
|
||||
Node::NodeType aNodeType)
|
||||
:mPrefix(aPrefix), mLocalName(aLocalName), mNamespace(aNSID),
|
||||
mNodeType(aNodeType)
|
||||
{
|
||||
if (aPrefix == txXMLAtoms::_empty)
|
||||
mPrefix = 0;
|
||||
NS_ASSERTION(aLocalName, "txNameTest without a local name?");
|
||||
TX_IF_ADDREF_ATOM(mPrefix);
|
||||
TX_IF_ADDREF_ATOM(mLocalName);
|
||||
}
|
||||
|
||||
txNameTest::~txNameTest()
|
||||
{
|
||||
TX_IF_RELEASE_ATOM(mPrefix);
|
||||
TX_IF_RELEASE_ATOM(mLocalName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether this txNodeTest matches the given node
|
||||
*/
|
||||
MBool txNameTest::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
if (!aNode || aNode->getNodeType() != mNodeType)
|
||||
return MB_FALSE;
|
||||
|
||||
// Totally wild?
|
||||
if (mLocalName == txXPathAtoms::_asterix && !mPrefix)
|
||||
return MB_TRUE;
|
||||
|
||||
// Compare namespaces
|
||||
if (aNode->getNamespaceID() != mNamespace)
|
||||
return MB_FALSE;
|
||||
|
||||
// Name wild?
|
||||
if (mLocalName == txXPathAtoms::_asterix)
|
||||
return MB_TRUE;
|
||||
|
||||
// Compare local-names
|
||||
txAtom* localName;
|
||||
aNode->getLocalName(&localName);
|
||||
MBool result = localName == mLocalName;
|
||||
TX_IF_RELEASE_ATOM(localName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default priority of this txNodeTest
|
||||
*/
|
||||
double txNameTest::getDefaultPriority()
|
||||
{
|
||||
if (mLocalName == txXPathAtoms::_asterix) {
|
||||
if (!mPrefix)
|
||||
return -0.5;
|
||||
return -0.25;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the String representation of this txNodeTest.
|
||||
* @param aDest the String to use when creating the string representation.
|
||||
* The string representation will be appended to the string.
|
||||
*/
|
||||
void txNameTest::toString(String& aDest)
|
||||
{
|
||||
if (mPrefix) {
|
||||
String prefix;
|
||||
TX_GET_ATOM_STRING(mPrefix, prefix);
|
||||
aDest.append(prefix);
|
||||
aDest.append(':');
|
||||
}
|
||||
String localName;
|
||||
TX_GET_ATOM_STRING(mLocalName, localName);
|
||||
aDest.append(localName);
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txNodeSetContext.h"
|
||||
|
||||
Node* txNodeSetContext::getContextNode()
|
||||
{
|
||||
return mContextSet->get(mPosition - 1);
|
||||
}
|
||||
|
||||
PRUint32 txNodeSetContext::size()
|
||||
{
|
||||
return (PRUint32)mContextSet->size();
|
||||
}
|
||||
|
||||
PRUint32 txNodeSetContext::position()
|
||||
{
|
||||
NS_ASSERTION(mPosition, "Should have called next() at least once");
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
nsresult txNodeSetContext::getVariable(PRInt32 aNamespace, txAtom* aLName,
|
||||
ExprResult*& aResult)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->getVariable(aNamespace, aLName, aResult);
|
||||
}
|
||||
|
||||
MBool txNodeSetContext::isStripSpaceAllowed(Node* aNode)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->isStripSpaceAllowed(aNode);
|
||||
}
|
||||
|
||||
void txNodeSetContext::receiveError(const String& aMsg, nsresult aRes)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
#ifdef DEBUG
|
||||
String error("forwarded error: ");
|
||||
error.append(aMsg);
|
||||
mInner->receiveError(error, aRes);
|
||||
#else
|
||||
mInner->receiveError(aMsg, aRes);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __TX_XPATH_SET_CONTEXT
|
||||
#define __TX_XPATH_SET_CONTEXT
|
||||
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
class txNodeSetContext : public txIEvalContext
|
||||
{
|
||||
public:
|
||||
txNodeSetContext(NodeSet* aContextNodeSet, txIMatchContext* aContext)
|
||||
: mContextSet(aContextNodeSet), mPosition(0), mInner(aContext)
|
||||
{
|
||||
}
|
||||
~txNodeSetContext()
|
||||
{
|
||||
}
|
||||
|
||||
// Iteration over the given NodeSet
|
||||
MBool hasNext()
|
||||
{
|
||||
return mPosition < size();
|
||||
}
|
||||
void next()
|
||||
{
|
||||
NS_ASSERTION(mPosition < size(), "Out of bounds.");
|
||||
mPosition++;
|
||||
}
|
||||
|
||||
TX_DECL_EVAL_CONTEXT;
|
||||
|
||||
private:
|
||||
NodeSet* mContextSet;
|
||||
PRUint32 mPosition;
|
||||
txIMatchContext* mInner;
|
||||
};
|
||||
|
||||
#endif // __TX_XPATH_SET_CONTEXT
|
|
@ -0,0 +1,121 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txAtom.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/*
|
||||
* Creates a new txNodeTypeTest of the given type
|
||||
*/
|
||||
txNodeTypeTest::txNodeTypeTest(NodeType aNodeType)
|
||||
: mNodeType(aNodeType), mNodeName(0)
|
||||
{
|
||||
}
|
||||
|
||||
txNodeTypeTest::~txNodeTypeTest()
|
||||
{
|
||||
TX_IF_RELEASE_ATOM(mNodeName);
|
||||
}
|
||||
|
||||
void txNodeTypeTest::setNodeName(const String& aName)
|
||||
{
|
||||
mNodeName = TX_GET_ATOM(aName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether this txNodeTest matches the given node
|
||||
*/
|
||||
MBool txNodeTypeTest::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
if (!aNode)
|
||||
return MB_FALSE;
|
||||
|
||||
Node::NodeType type = (Node::NodeType)aNode->getNodeType();
|
||||
|
||||
switch (mNodeType) {
|
||||
case COMMENT_TYPE:
|
||||
return type == Node::COMMENT_NODE;
|
||||
case TEXT_TYPE:
|
||||
return (type == Node::TEXT_NODE ||
|
||||
type == Node::CDATA_SECTION_NODE) &&
|
||||
!aContext->isStripSpaceAllowed(aNode);
|
||||
case PI_TYPE:
|
||||
if (type == Node::PROCESSING_INSTRUCTION_NODE) {
|
||||
txAtom* localName = 0;
|
||||
MBool result;
|
||||
result = !mNodeName ||
|
||||
(aNode->getLocalName(&localName) &&
|
||||
localName == mNodeName);
|
||||
TX_IF_RELEASE_ATOM(localName);
|
||||
return result;
|
||||
}
|
||||
return MB_FALSE;
|
||||
case NODE_TYPE:
|
||||
return ((type != Node::TEXT_NODE &&
|
||||
type != Node::CDATA_SECTION_NODE) ||
|
||||
!aContext->isStripSpaceAllowed(aNode));
|
||||
}
|
||||
return MB_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default priority of this txNodeTest
|
||||
*/
|
||||
double txNodeTypeTest::getDefaultPriority()
|
||||
{
|
||||
return mNodeName ? 0 : -0.5;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the String representation of this txNodeTest.
|
||||
* @param aDest the String to use when creating the string representation.
|
||||
* The string representation will be appended to the string.
|
||||
*/
|
||||
void txNodeTypeTest::toString(String& aDest)
|
||||
{
|
||||
switch (mNodeType) {
|
||||
case COMMENT_TYPE:
|
||||
aDest.append("comment()");
|
||||
break;
|
||||
case TEXT_TYPE:
|
||||
aDest.append("text()");
|
||||
break;
|
||||
case PI_TYPE:
|
||||
aDest.append("processing-instruction(");
|
||||
if (mNodeName) {
|
||||
String str;
|
||||
TX_GET_ATOM_STRING(mNodeName, str);
|
||||
aDest.append('\'');
|
||||
aDest.append(str);
|
||||
aDest.append('\'');
|
||||
}
|
||||
aDest.append(')');
|
||||
break;
|
||||
case NODE_TYPE:
|
||||
aDest.append("node()");
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __TX_XPATH_SINGLENODE_CONTEXT
|
||||
#define __TX_XPATH_SINGLENODE_CONTEXT
|
||||
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
class txSingleNodeContext : public txIEvalContext
|
||||
{
|
||||
public:
|
||||
txSingleNodeContext(Node* aContextNode, txIMatchContext* aContext)
|
||||
: mNode(aContextNode), mInner(aContext)
|
||||
{
|
||||
NS_ASSERTION(aContextNode, "context node must be given");
|
||||
NS_ASSERTION(aContext, "txIMatchContext must be given");
|
||||
}
|
||||
~txSingleNodeContext()
|
||||
{}
|
||||
|
||||
nsresult getVariable(PRInt32 aNamespace, txAtom* aLName,
|
||||
ExprResult*& aResult)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->getVariable(aNamespace, aLName, aResult);
|
||||
}
|
||||
|
||||
MBool isStripSpaceAllowed(Node* aNode)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
return mInner->isStripSpaceAllowed(aNode);
|
||||
}
|
||||
|
||||
void receiveError(const String& aMsg, nsresult aRes)
|
||||
{
|
||||
NS_ASSERTION(mInner, "mInner is null!!!");
|
||||
#ifdef DEBUG
|
||||
String error("forwarded error: ");
|
||||
error.append(aMsg);
|
||||
mInner->receiveError(error, aRes);
|
||||
#else
|
||||
mInner->receiveError(aMsg, aRes);
|
||||
#endif
|
||||
}
|
||||
|
||||
Node* getContextNode()
|
||||
{
|
||||
return mNode;
|
||||
}
|
||||
|
||||
PRUint32 size()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
PRUint32 position()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
Node* mNode;
|
||||
txIMatchContext* mInner;
|
||||
};
|
||||
|
||||
#endif // __TX_XPATH_SINGLENODE_CONTEXT
|
|
@ -54,6 +54,8 @@ CPPSRCS = Names.cpp \
|
|||
txRtfHandler.cpp \
|
||||
txTextHandler.cpp \
|
||||
VariableBinding.cpp \
|
||||
txXSLTPatterns.cpp \
|
||||
txPatternParser.cpp \
|
||||
XSLTProcessor.cpp
|
||||
|
||||
ifdef TX_EXE
|
||||
|
|
|
@ -31,8 +31,9 @@
|
|||
#include "Numbering.h"
|
||||
#include "Names.h"
|
||||
#include "txAtoms.h"
|
||||
#include "XMLUtils.h"
|
||||
|
||||
void Numbering::doNumbering(Element* xslNumber, String& dest, Node* context,
|
||||
void Numbering::doNumbering(Element* xslNumber, String& dest,
|
||||
ProcessorState* ps)
|
||||
{
|
||||
if (!xslNumber)
|
||||
|
@ -41,30 +42,31 @@ void Numbering::doNumbering(Element* xslNumber, String& dest, Node* context,
|
|||
int* counts = 0;
|
||||
int nbrOfCounts = 0;
|
||||
|
||||
String valueAttr;
|
||||
xslNumber->getAttr(txXSLTAtoms::value, kNameSpaceID_None,
|
||||
valueAttr);
|
||||
//-- check for expr
|
||||
if (!valueAttr.isEmpty()) {
|
||||
if (xslNumber->hasAttr(txXSLTAtoms::value, kNameSpaceID_None)) {
|
||||
Expr* expr = ps->getExpr(xslNumber, ProcessorState::ValueAttr);
|
||||
if (!expr)
|
||||
if (!expr) {
|
||||
// XXX error reporting, parse failed
|
||||
return;
|
||||
}
|
||||
ExprResult* result = expr->evaluate(ps->getEvalContext());
|
||||
double dbl = Double::NaN;
|
||||
if (result)
|
||||
dbl = result->numberValue();
|
||||
delete result;
|
||||
nbrOfCounts = 1;
|
||||
counts = new int[1];
|
||||
ExprResult* result = expr->evaluate(context, ps);
|
||||
double dbl = result->numberValue();
|
||||
delete result;
|
||||
counts[0] = (int)dbl;
|
||||
}
|
||||
else if (context) {
|
||||
|
||||
//-- create count expression
|
||||
else {
|
||||
Node* context = ps->getEvalContext()->getContextNode();
|
||||
|
||||
// create count pattern
|
||||
String countAttr;
|
||||
xslNumber->getAttr(txXSLTAtoms::count, kNameSpaceID_None,
|
||||
countAttr);
|
||||
|
||||
Pattern* countPattern;
|
||||
txPattern* countPattern = 0;
|
||||
MBool ownsPattern;
|
||||
|
||||
if (!countAttr.isEmpty()) {
|
||||
|
@ -73,31 +75,52 @@ void Numbering::doNumbering(Element* xslNumber, String& dest, Node* context,
|
|||
ownsPattern = MB_FALSE;
|
||||
}
|
||||
else {
|
||||
// Actually, this code should probobly use NodeTests instead
|
||||
MBool isAttr = MB_FALSE;
|
||||
Node::NodeType type = Node::ELEMENT_NODE;
|
||||
txNodeTypeTest::NodeType nodetype;
|
||||
switch(context->getNodeType()) {
|
||||
case Node::ATTRIBUTE_NODE:
|
||||
countAttr.append('@');
|
||||
countAttr.append(context->getNodeName());
|
||||
break;
|
||||
isAttr = MB_TRUE;
|
||||
type = Node::ATTRIBUTE_NODE;
|
||||
case Node::ELEMENT_NODE:
|
||||
countAttr.append(context->getNodeName());
|
||||
{
|
||||
const String& name = context->getNodeName();
|
||||
String prefix, lname;
|
||||
XMLUtils::getPrefix(name, prefix);
|
||||
XMLUtils::getLocalPart(name, lname);
|
||||
txAtom* prefixAtom = 0;
|
||||
if (!prefix.isEmpty()) {
|
||||
prefixAtom = TX_GET_ATOM(prefix);
|
||||
}
|
||||
txAtom* lNameAtom = TX_GET_ATOM(lname);
|
||||
PRInt32 NSid = context->getNamespaceID();
|
||||
txNameTest* nt = new txNameTest(prefixAtom, lNameAtom,
|
||||
NSid, type);
|
||||
TX_IF_RELEASE_ATOM(prefixAtom);
|
||||
TX_IF_RELEASE_ATOM(lNameAtom);
|
||||
countPattern = new txStepPattern(nt, isAttr);
|
||||
}
|
||||
break;
|
||||
case Node::CDATA_SECTION_NODE :
|
||||
case Node::TEXT_NODE :
|
||||
countAttr.append("text()");
|
||||
nodetype = txNodeTypeTest::TEXT_TYPE;
|
||||
break;
|
||||
case Node::COMMENT_NODE :
|
||||
countAttr.append("comment()");
|
||||
nodetype = txNodeTypeTest::COMMENT_TYPE;
|
||||
break;
|
||||
case Node::PROCESSING_INSTRUCTION_NODE :
|
||||
countAttr.append("processing-instruction()");
|
||||
nodetype = txNodeTypeTest::PI_TYPE;
|
||||
break;
|
||||
default:
|
||||
countAttr.append("node()[false()]"); //-- for now
|
||||
break;
|
||||
NS_ASSERTION(0, "Unexpected Node type");
|
||||
delete counts;
|
||||
return;
|
||||
}
|
||||
if (!countPattern) {
|
||||
// not a nametest
|
||||
txNodeTypeTest* nt = new txNodeTypeTest(nodetype);
|
||||
countPattern = new txStepPattern(nt, MB_FALSE);
|
||||
}
|
||||
ExprParser parser;
|
||||
countPattern = parser.createPattern(countAttr);
|
||||
ownsPattern = MB_TRUE;
|
||||
}
|
||||
if (!countPattern) {
|
||||
|
@ -114,7 +137,7 @@ void Numbering::doNumbering(Element* xslNumber, String& dest, Node* context,
|
|||
String fromAttr;
|
||||
xslNumber->getAttr(txXSLTAtoms::from, kNameSpaceID_None,
|
||||
fromAttr);
|
||||
PatternExpr* from = 0;
|
||||
txPattern* from = 0;
|
||||
|
||||
if (MULTIPLE_VALUE.isEqual(level))
|
||||
nodes = getAncestorsOrSelf(countPattern,
|
||||
|
@ -150,7 +173,7 @@ void Numbering::doNumbering(Element* xslNumber, String& dest, Node* context,
|
|||
} //-- doNumbering
|
||||
|
||||
int Numbering::countPreceedingSiblings
|
||||
(PatternExpr* patternExpr, Node* context, ProcessorState* ps)
|
||||
(txPattern* patternExpr, Node* context, ProcessorState* ps)
|
||||
{
|
||||
int count = 1;
|
||||
|
||||
|
@ -158,26 +181,27 @@ int Numbering::countPreceedingSiblings
|
|||
|
||||
Node* sibling = context;
|
||||
while ((sibling = sibling->getPreviousSibling())) {
|
||||
if (patternExpr->matches(sibling, sibling, ps))
|
||||
if (patternExpr->matches(sibling, ps))
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
} //-- countPreceedingSiblings
|
||||
|
||||
NodeSet* Numbering::getAncestorsOrSelf
|
||||
( PatternExpr* countExpr,
|
||||
PatternExpr* from,
|
||||
Node* context,
|
||||
ProcessorState* ps,
|
||||
MBool findNearest)
|
||||
(txPattern* countExpr,
|
||||
txPattern* from,
|
||||
Node* context,
|
||||
ProcessorState* ps,
|
||||
MBool findNearest)
|
||||
{
|
||||
NodeSet* nodeSet = new NodeSet();
|
||||
Node* parent = context;
|
||||
while ((parent) && (parent->getNodeType() == Node::ELEMENT_NODE))
|
||||
{
|
||||
if ((from) && from->matches(parent, parent->getParentNode(), ps)) break;
|
||||
if (from && from->matches(parent, ps))
|
||||
break;
|
||||
|
||||
if (countExpr->matches(parent, parent->getParentNode(), ps)) {
|
||||
if (countExpr->matches(parent, ps)) {
|
||||
nodeSet->append(parent);
|
||||
if (findNearest) break;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "baseutils.h"
|
||||
#include "TxString.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "Expr.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "primitives.h"
|
||||
#include "ExprResult.h"
|
||||
|
||||
|
@ -41,19 +41,19 @@ class Numbering {
|
|||
|
||||
public:
|
||||
|
||||
static void doNumbering
|
||||
(Element* xslNumber, String& dest, Node* context, ProcessorState* ps);
|
||||
static void doNumbering(Element* xslNumber, String& dest,
|
||||
ProcessorState* ps);
|
||||
|
||||
private:
|
||||
static int countPreceedingSiblings
|
||||
(PatternExpr* patternExpr, Node* context, ProcessorState* ps);
|
||||
(txPattern* patternExpr, Node* context, ProcessorState* ps);
|
||||
|
||||
static NodeSet* getAncestorsOrSelf
|
||||
( PatternExpr* countExpr,
|
||||
PatternExpr* from,
|
||||
Node* context,
|
||||
ProcessorState* ps,
|
||||
MBool findNearest );
|
||||
(txPattern* countExpr,
|
||||
txPattern* from,
|
||||
Node* context,
|
||||
ProcessorState* ps,
|
||||
MBool findNearest );
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -49,8 +49,7 @@
|
|||
/**
|
||||
* Creates a new ProcessorState
|
||||
**/
|
||||
ProcessorState::ProcessorState() : mXPathParseContext(0),
|
||||
mSourceDocument(0),
|
||||
ProcessorState::ProcessorState() : mEvalContext(0), mSourceDocument(0),
|
||||
xslDocument(0),
|
||||
resultDocument(0)
|
||||
{
|
||||
|
@ -64,8 +63,7 @@ ProcessorState::ProcessorState() : mXPathParseContext(0),
|
|||
ProcessorState::ProcessorState(Document* aSourceDocument,
|
||||
Document* aXslDocument,
|
||||
Document* aResultDocument)
|
||||
: mXPathParseContext(0),
|
||||
mSourceDocument(aSourceDocument),
|
||||
: mEvalContext(0), mSourceDocument(aSourceDocument),
|
||||
xslDocument(aXslDocument),
|
||||
resultDocument(aResultDocument)
|
||||
{
|
||||
|
@ -112,7 +110,7 @@ void ProcessorState::addAttributeSet(Element* aAttributeSet,
|
|||
if (!aAttributeSet->getAttr(txXSLTAtoms::name,
|
||||
kNameSpaceID_None, name)) {
|
||||
String err("missing required name attribute for xsl:attribute-set");
|
||||
recieveError(err);
|
||||
receiveError(err);
|
||||
return;
|
||||
}
|
||||
// Get attribute set, if already exists, then merge
|
||||
|
@ -165,45 +163,89 @@ void ProcessorState::addTemplate(Element* aXslTemplate,
|
|||
if (tmp) {
|
||||
String err("Duplicate template name: ");
|
||||
err.append(name);
|
||||
recieveError(err);
|
||||
receiveError(err);
|
||||
return;
|
||||
}
|
||||
aImportFrame->mNamedTemplates.put(name, aXslTemplate);
|
||||
}
|
||||
|
||||
String match;
|
||||
if (aXslTemplate->getAttr(txXSLTAtoms::match,
|
||||
kNameSpaceID_None, match)) {
|
||||
// get the txList for the right mode
|
||||
String mode;
|
||||
aXslTemplate->getAttr(txXSLTAtoms::mode, kNameSpaceID_None, mode);
|
||||
txList* templates =
|
||||
(txList*)aImportFrame->mMatchableTemplates.get(mode);
|
||||
if (!aXslTemplate->getAttr(txXSLTAtoms::match, kNameSpaceID_None, match)) {
|
||||
// This is no error, see section 6 Named Templates
|
||||
return;
|
||||
}
|
||||
// get the txList for the right mode
|
||||
String mode;
|
||||
aXslTemplate->getAttr(txXSLTAtoms::mode, kNameSpaceID_None, mode);
|
||||
txList* templates =
|
||||
(txList*)aImportFrame->mMatchableTemplates.get(mode);
|
||||
|
||||
if (!templates) {
|
||||
templates = new txList;
|
||||
if (!templates) {
|
||||
templates = new txList;
|
||||
if (!templates) {
|
||||
NS_ASSERTION(0, "out of memory");
|
||||
return;
|
||||
}
|
||||
aImportFrame->mMatchableTemplates.put(mode, templates);
|
||||
}
|
||||
|
||||
// Add the template to the list of templates
|
||||
MatchableTemplate* templ = new MatchableTemplate;
|
||||
if (!templ) {
|
||||
NS_ASSERTION(0, "out of memory");
|
||||
return;
|
||||
}
|
||||
templ->mTemplate = aXslTemplate;
|
||||
Element* oldContext = mXPathParseContext;
|
||||
mXPathParseContext = aXslTemplate;
|
||||
templ->mMatch = exprParser.createPattern(match);
|
||||
mXPathParseContext = oldContext;
|
||||
if (templ->mMatch)
|
||||
templates->add(templ);
|
||||
else
|
||||
delete templ;
|
||||
aImportFrame->mMatchableTemplates.put(mode, templates);
|
||||
}
|
||||
|
||||
// Check for explicit default priority
|
||||
MBool hasPriority;
|
||||
double priority;
|
||||
String prio;
|
||||
if ((hasPriority =
|
||||
aXslTemplate->getAttr(txXSLTAtoms::priority, kNameSpaceID_None,
|
||||
prio))) {
|
||||
priority = Double::toDouble(prio);
|
||||
}
|
||||
|
||||
// Get the pattern
|
||||
txPSParseContext context(this, aXslTemplate);
|
||||
txPattern* pattern = txPatternParser::createPattern(match, &context, this);
|
||||
#ifdef TX_PATTERN_DEBUG
|
||||
String foo;
|
||||
pattern->toString(foo);
|
||||
#endif
|
||||
|
||||
if (!pattern) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the simple patterns to the list of matchable templates, according
|
||||
// to default priority
|
||||
txList simpleMatches;
|
||||
pattern->getSimplePatterns(simpleMatches);
|
||||
txListIterator simples(&simpleMatches);
|
||||
while (simples.hasNext()) {
|
||||
txPattern* simple = (txPattern*)simples.next();
|
||||
if (simple != pattern && pattern) {
|
||||
// txUnionPattern, it doesn't own the txLocPathPatterns no more,
|
||||
// so delete it. (only once, of course)
|
||||
delete pattern;
|
||||
pattern = 0;
|
||||
}
|
||||
if (!hasPriority) {
|
||||
priority = simple->getDefaultPriority();
|
||||
}
|
||||
MatchableTemplate* nt = new MatchableTemplate(aXslTemplate,
|
||||
simple,
|
||||
priority);
|
||||
if (!nt) {
|
||||
NS_ASSERTION(0, "out of mem");
|
||||
return;
|
||||
}
|
||||
txListIterator templ(templates);
|
||||
MBool isLast = MB_TRUE;
|
||||
while (templ.hasNext() && isLast) {
|
||||
MatchableTemplate* mt = (MatchableTemplate*)templ.next();
|
||||
if (priority < mt->mPriority) {
|
||||
continue;
|
||||
}
|
||||
templ.addBefore(nt);
|
||||
isLast = MB_FALSE;
|
||||
}
|
||||
if (isLast)
|
||||
templates->add(nt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,19 +273,27 @@ void ProcessorState::addLREStylesheet(Document* aStylesheet,
|
|||
}
|
||||
|
||||
// Add the template to the list of templates
|
||||
MatchableTemplate* templ = new MatchableTemplate;
|
||||
if (!templ) {
|
||||
txPattern* root = new txRootPattern(MB_TRUE);
|
||||
MatchableTemplate* nt = 0;
|
||||
if (root)
|
||||
nt = new MatchableTemplate(aStylesheet, root, Double::NaN);
|
||||
if (!nt) {
|
||||
delete root;
|
||||
// XXX ErrorReport: out of memory
|
||||
return;
|
||||
}
|
||||
|
||||
templ->mTemplate = aStylesheet;
|
||||
String match("/");
|
||||
templ->mMatch = exprParser.createPattern(match);
|
||||
if (templ->mMatch)
|
||||
templates->add(templ);
|
||||
else
|
||||
delete templ;
|
||||
txListIterator templ(templates);
|
||||
MBool isLast = MB_TRUE;
|
||||
while (templ.hasNext() && isLast) {
|
||||
MatchableTemplate* mt = (MatchableTemplate*)templ.next();
|
||||
if (0.5 < mt->mPriority) {
|
||||
continue;
|
||||
}
|
||||
templ.addBefore(nt);
|
||||
isLast = MB_FALSE;
|
||||
}
|
||||
if (isLast)
|
||||
templates->add(nt);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -279,7 +329,7 @@ Node* ProcessorState::retrieveDocument(const String& uri, const String& baseUri)
|
|||
err.append(docUrl);
|
||||
err.append("': ");
|
||||
err.append(errMsg);
|
||||
recieveError(err, ErrorObserver::WARNING);
|
||||
receiveError(err, NS_ERROR_XSLT_INVALID_URL);
|
||||
return NULL;
|
||||
}
|
||||
// add to list of documents
|
||||
|
@ -373,31 +423,15 @@ Node* ProcessorState::findTemplate(Node* aNode,
|
|||
|
||||
// Find template with highest priority
|
||||
MatchableTemplate* templ;
|
||||
while ((templ = (MatchableTemplate*)templateIter.next())) {
|
||||
String priorityAttr;
|
||||
|
||||
if (templ->mTemplate->getNodeType() == Node::ELEMENT_NODE) {
|
||||
Element* elem = (Element*)templ->mTemplate;
|
||||
elem->getAttr(txXSLTAtoms::priority, kNameSpaceID_None,
|
||||
priorityAttr);
|
||||
}
|
||||
|
||||
double tmpPriority;
|
||||
if (!priorityAttr.isEmpty()) {
|
||||
tmpPriority = Double::toDouble(priorityAttr);
|
||||
}
|
||||
else {
|
||||
tmpPriority = templ->mMatch->getDefaultPriority(aNode,
|
||||
0,
|
||||
this);
|
||||
}
|
||||
|
||||
if (tmpPriority >= currentPriority &&
|
||||
templ->mMatch->matches(aNode, 0, this)) {
|
||||
|
||||
while (!matchTemplate &&
|
||||
(templ = (MatchableTemplate*)templateIter.next())) {
|
||||
#ifdef TX_PATTERN_DEBUG
|
||||
String foo;
|
||||
templ->mMatch->toString(foo);
|
||||
#endif
|
||||
if (templ->mMatch->matches(aNode, this)) {
|
||||
matchTemplate = templ->mTemplate;
|
||||
*aImportFrame = frame;
|
||||
currentPriority = tmpPriority;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -467,91 +501,83 @@ NodeSet* ProcessorState::getAttributeSet(const String& aName)
|
|||
return attset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source node currently being processed
|
||||
**/
|
||||
Node* ProcessorState::getCurrentNode() {
|
||||
return currentNodeStack.peek();
|
||||
} //-- setCurrentNode
|
||||
|
||||
Expr* ProcessorState::getExpr(Element* aElem, ExprAttr aAttr)
|
||||
{
|
||||
NS_ASSERTION(aElem, "missing element while getting expression");
|
||||
|
||||
// This is how we'll have to do it for now
|
||||
mXPathParseContext = aElem;
|
||||
|
||||
Expr* expr = (Expr*)mExprHashes[aAttr].get(aElem);
|
||||
if (expr) {
|
||||
return expr;
|
||||
}
|
||||
String attr;
|
||||
MBool hasAttr;
|
||||
switch (aAttr) {
|
||||
case SelectAttr:
|
||||
hasAttr = aElem->getAttr(txXSLTAtoms::select, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
case TestAttr:
|
||||
hasAttr = aElem->getAttr(txXSLTAtoms::test, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
case ValueAttr:
|
||||
hasAttr = aElem->getAttr(txXSLTAtoms::value, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasAttr)
|
||||
return 0;
|
||||
|
||||
txPSParseContext pContext(this, aElem);
|
||||
expr = ExprParser::createExpr(attr, &pContext);
|
||||
|
||||
if (!expr) {
|
||||
String attr;
|
||||
switch (aAttr) {
|
||||
case SelectAttr:
|
||||
aElem->getAttr(txXSLTAtoms::select, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
case TestAttr:
|
||||
aElem->getAttr(txXSLTAtoms::test, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
case ValueAttr:
|
||||
aElem->getAttr(txXSLTAtoms::value, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
}
|
||||
|
||||
// This is how we should do it once we namespaceresolve during parsing
|
||||
//Element* oldContext = mXPathParseContext;
|
||||
//mXPathParseContext = aElem;
|
||||
expr = exprParser.createExpr(attr);
|
||||
//mXPathParseContext = oldContext;
|
||||
|
||||
if (!expr) {
|
||||
String err = "Error in parsing XPath expression: ";
|
||||
err.append(attr);
|
||||
recieveError(err);
|
||||
}
|
||||
else {
|
||||
mExprHashes[aAttr].put(aElem, expr);
|
||||
}
|
||||
String err = "Error in parsing XPath expression: ";
|
||||
err.append(attr);
|
||||
receiveError(err, NS_ERROR_XPATH_PARSE_FAILED);
|
||||
}
|
||||
else {
|
||||
mExprHashes[aAttr].put(aElem, expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
||||
PatternExpr* ProcessorState::getPattern(Element* aElem, PatternAttr aAttr)
|
||||
txPattern* ProcessorState::getPattern(Element* aElem, PatternAttr aAttr)
|
||||
{
|
||||
NS_ASSERTION(aElem, "missing element while getting pattern");
|
||||
|
||||
// This is how we'll have to do it for now
|
||||
mXPathParseContext = aElem;
|
||||
txPattern* pattern = (txPattern*)mPatternHashes[aAttr].get(aElem);
|
||||
if (pattern) {
|
||||
return pattern;
|
||||
}
|
||||
String attr;
|
||||
MBool hasAttr;
|
||||
switch (aAttr) {
|
||||
case CountAttr:
|
||||
hasAttr = aElem->getAttr(txXSLTAtoms::count, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
case FromAttr:
|
||||
hasAttr = aElem->getAttr(txXSLTAtoms::from, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!hasAttr)
|
||||
return 0;
|
||||
|
||||
|
||||
txPSParseContext pContext(this, aElem);
|
||||
pattern = txPatternParser::createPattern(attr, &pContext, this);
|
||||
|
||||
Pattern* pattern = (Pattern*)mExprHashes[aAttr].get(aElem);
|
||||
if (!pattern) {
|
||||
String attr;
|
||||
switch (aAttr) {
|
||||
case CountAttr:
|
||||
aElem->getAttr(txXSLTAtoms::count, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
case FromAttr:
|
||||
aElem->getAttr(txXSLTAtoms::from, kNameSpaceID_None,
|
||||
attr);
|
||||
break;
|
||||
}
|
||||
|
||||
// This is how we should do it once we namespaceresolve during parsing
|
||||
//Element* oldContext = mXPathParseContext;
|
||||
//mXPathParseContext = aElem;
|
||||
pattern = exprParser.createPattern(attr);
|
||||
//mXPathParseContext = oldContext;
|
||||
|
||||
if (!pattern) {
|
||||
String err = "Error in parsing pattern: ";
|
||||
err.append(attr);
|
||||
recieveError(err);
|
||||
}
|
||||
else {
|
||||
mPatternHashes[aAttr].put(aElem, pattern);
|
||||
}
|
||||
String err = "Error in parsing pattern: ";
|
||||
err.append(attr);
|
||||
receiveError(err, NS_ERROR_XPATH_PARSE_FAILED);
|
||||
}
|
||||
else {
|
||||
mPatternHashes[aAttr].put(aElem, pattern);
|
||||
}
|
||||
return pattern;
|
||||
}
|
||||
|
@ -573,14 +599,6 @@ Element* ProcessorState::getNamedTemplate(String& aName)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ProcessorState::getNameSpaceURIFromPrefix(const String& aPrefix,
|
||||
String& aNamespaceURI)
|
||||
{
|
||||
if (mXPathParseContext)
|
||||
XMLDOMUtils::getNamespaceURI(aPrefix, mXPathParseContext,
|
||||
aNamespaceURI);
|
||||
}
|
||||
|
||||
txOutputFormat* ProcessorState::getOutputFormat()
|
||||
{
|
||||
return &mOutputFormat;
|
||||
|
@ -607,27 +625,22 @@ MBool ProcessorState::isXSLStripSpaceAllowed(Node* node) {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and returns the current source node being processed, from the stack
|
||||
* @return the current source node
|
||||
**/
|
||||
Node* ProcessorState::popCurrentNode() {
|
||||
return currentNodeStack.pop();
|
||||
} //-- popCurrentNode
|
||||
|
||||
void ProcessorState::processAttrValueTemplate(const String& aAttValue,
|
||||
Node* aContext,
|
||||
Element* aContext,
|
||||
String& aResult)
|
||||
{
|
||||
aResult.clear();
|
||||
txPSParseContext pContext(this, aContext);
|
||||
AttributeValueTemplate* avt =
|
||||
exprParser.createAttributeValueTemplate(aAttValue);
|
||||
ExprParser::createAttributeValueTemplate(aAttValue, &pContext);
|
||||
|
||||
if (!avt) {
|
||||
// XXX ErrorReport: out of memory
|
||||
// fallback, just copy the attribute
|
||||
aResult.append(aAttValue);
|
||||
return;
|
||||
}
|
||||
|
||||
ExprResult* exprResult = avt->evaluate(aContext, this);
|
||||
ExprResult* exprResult = avt->evaluate(this->getEvalContext());
|
||||
delete avt;
|
||||
if (!exprResult) {
|
||||
// XXX ErrorReport: out of memory
|
||||
|
@ -638,20 +651,12 @@ void ProcessorState::processAttrValueTemplate(const String& aAttValue,
|
|||
delete exprResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source node currently being processed
|
||||
* @param node the source node to set as the "current" node
|
||||
**/
|
||||
void ProcessorState::pushCurrentNode(Node* node) {
|
||||
currentNodeStack.push(node);
|
||||
} //-- setCurrentNode
|
||||
|
||||
/**
|
||||
* Adds the set of names to the Whitespace handling list.
|
||||
* xsl:strip-space calls this with MB_TRUE, xsl:preserve-space
|
||||
* with MB_FALSE
|
||||
*/
|
||||
void ProcessorState::shouldStripSpace(String& aNames,
|
||||
void ProcessorState::shouldStripSpace(String& aNames, Element* aElement,
|
||||
MBool aShouldStrip,
|
||||
ImportFrame* aImportFrame)
|
||||
{
|
||||
|
@ -660,7 +665,20 @@ void ProcessorState::shouldStripSpace(String& aNames,
|
|||
String name;
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
tokenizer.nextToken(name);
|
||||
txNameTestItem* nti = new txNameTestItem(name, aShouldStrip);
|
||||
String prefix, lname;
|
||||
PRInt32 aNSID = kNameSpaceID_None;
|
||||
txAtom* prefixAtom = 0;
|
||||
XMLUtils::getPrefix(name, prefix);
|
||||
if (!prefix.isEmpty()) {
|
||||
prefixAtom = TX_GET_ATOM(prefix);
|
||||
aNSID = aElement->lookupNamespaceID(prefixAtom);
|
||||
}
|
||||
XMLUtils::getLocalPart(name, lname);
|
||||
txAtom* lNameAtom = TX_GET_ATOM(lname);
|
||||
txNameTestItem* nti = new txNameTestItem(prefixAtom, lNameAtom,
|
||||
aNSID, aShouldStrip);
|
||||
TX_IF_RELEASE_ATOM(prefixAtom);
|
||||
TX_IF_RELEASE_ATOM(lNameAtom);
|
||||
if (!nti) {
|
||||
// XXX error report, parsing error or out of mem
|
||||
break;
|
||||
|
@ -694,15 +712,17 @@ MBool ProcessorState::addKey(Element* aKeyElem)
|
|||
return MB_FALSE;
|
||||
xslKeys.put(keyName, xslKey);
|
||||
}
|
||||
Element* oldContext = mXPathParseContext;
|
||||
mXPathParseContext = aKeyElem;
|
||||
Pattern* match;
|
||||
String matchAttr, useAttr;
|
||||
aKeyElem->getAttr(txXSLTAtoms::match, kNameSpaceID_None, matchAttr);
|
||||
aKeyElem->getAttr(txXSLTAtoms::use, kNameSpaceID_None, useAttr);
|
||||
match = exprParser.createPattern(matchAttr);
|
||||
Expr* use = exprParser.createExpr(useAttr);
|
||||
mXPathParseContext = oldContext;
|
||||
txPattern* match = 0;
|
||||
txPSParseContext pContext(this, aKeyElem);
|
||||
String attrVal;
|
||||
if (aKeyElem->getAttr(txXSLTAtoms::match, kNameSpaceID_None, attrVal)) {
|
||||
match = txPatternParser::createPattern(attrVal, &pContext, this);
|
||||
}
|
||||
Expr* use = 0;
|
||||
attrVal.clear();
|
||||
if (aKeyElem->getAttr(txXSLTAtoms::use, kNameSpaceID_None, attrVal)) {
|
||||
use = ExprParser::createExpr(attrVal, &pContext);
|
||||
}
|
||||
if (!match || !use || !xslKey->addKey(match, use)) {
|
||||
delete match;
|
||||
delete use;
|
||||
|
@ -845,27 +865,18 @@ txDecimalFormat* ProcessorState::getDecimalFormat(String& name)
|
|||
return (txDecimalFormat*)decimalFormats.get(name);
|
||||
}
|
||||
|
||||
//--------------------------------------------------/
|
||||
//- Virtual Methods from derived from ContextState -/
|
||||
//--------------------------------------------------/
|
||||
|
||||
|
||||
/**
|
||||
* Returns the Stack of context NodeSets
|
||||
* @return the Stack of context NodeSets
|
||||
**/
|
||||
Stack* ProcessorState::getNodeSetStack() {
|
||||
return &nodeSetStack;
|
||||
} //-- getNodeSetStack
|
||||
|
||||
/**
|
||||
* Returns the value of a given variable binding within the current scope
|
||||
* @param the name to which the desired variable value has been bound
|
||||
* @return the ExprResult which has been bound to the variable with the given
|
||||
* name
|
||||
**/
|
||||
ExprResult* ProcessorState::getVariable(String& name) {
|
||||
|
||||
nsresult ProcessorState::getVariable(PRInt32 aNamespace, txAtom* aLName,
|
||||
ExprResult*& aResult)
|
||||
{
|
||||
String name;
|
||||
// XXX TODO, bug 117658
|
||||
TX_GET_ATOM_STRING(aLName, name);
|
||||
StackIterator* iter = variableSets.iterator();
|
||||
ExprResult* exprResult = 0;
|
||||
while (iter->hasNext()) {
|
||||
|
@ -876,7 +887,8 @@ ExprResult* ProcessorState::getVariable(String& name) {
|
|||
}
|
||||
}
|
||||
delete iter;
|
||||
return exprResult;
|
||||
aResult = exprResult;
|
||||
return aResult ? NS_OK : NS_ERROR_INVALID_ARG;
|
||||
} //-- getVariable
|
||||
|
||||
/**
|
||||
|
@ -929,69 +941,71 @@ MBool ProcessorState::isStripSpaceAllowed(Node* node)
|
|||
return (MBool)(STRIP == mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error, with default
|
||||
* level of NORMAL
|
||||
**/
|
||||
void ProcessorState::recieveError(String& errorMessage) {
|
||||
recieveError(errorMessage, ErrorObserver::NORMAL);
|
||||
} //-- recieveError
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error using the given error level
|
||||
**/
|
||||
void ProcessorState::recieveError(String& errorMessage, ErrorLevel level) {
|
||||
ListIterator* iter = errorObservers.iterator();
|
||||
while (iter->hasNext()) {
|
||||
ErrorObserver* observer = (ErrorObserver*)iter->next();
|
||||
observer->recieveError(errorMessage, level);
|
||||
void ProcessorState::receiveError(const String& errorMessage, nsresult aRes)
|
||||
{
|
||||
ListIterator iter(&errorObservers);
|
||||
while (iter.hasNext()) {
|
||||
ErrorObserver* observer = (ErrorObserver*)iter.next();
|
||||
observer->receiveError(errorMessage, aRes);
|
||||
}
|
||||
delete iter;
|
||||
} //-- recieveError
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a call to the function that has the given name.
|
||||
* This method is used for XPath Extension Functions.
|
||||
* @return the FunctionCall for the function with the given name.
|
||||
**/
|
||||
FunctionCall* ProcessorState::resolveFunctionCall(const String& name) {
|
||||
String err;
|
||||
#define CHECK_FN(_name) aName == txXSLTAtoms::##_name
|
||||
|
||||
if (DOCUMENT_FN.isEqual(name)) {
|
||||
return new DocumentFunctionCall(this, mXPathParseContext);
|
||||
nsresult ProcessorState::resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
||||
Element* aElem,
|
||||
FunctionCall*& aFunction)
|
||||
{
|
||||
aFunction = 0;
|
||||
|
||||
if (aID != kNameSpaceID_None) {
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
}
|
||||
else if (KEY_FN.isEqual(name)) {
|
||||
return new txKeyFunctionCall(this);
|
||||
if (CHECK_FN(document)) {
|
||||
aFunction = new DocumentFunctionCall(this, aElem);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (FORMAT_NUMBER_FN.isEqual(name)) {
|
||||
return new txFormatNumberFunctionCall(this);
|
||||
if (CHECK_FN(key)) {
|
||||
aFunction = new txKeyFunctionCall(this);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (CURRENT_FN.isEqual(name)) {
|
||||
return new CurrentFunctionCall(this);
|
||||
if (CHECK_FN(formatNumber)) {
|
||||
aFunction = new txFormatNumberFunctionCall(this);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (UNPARSED_ENTITY_URI_FN.isEqual(name)) {
|
||||
err = "function not yet implemented: ";
|
||||
err.append(name);
|
||||
if (CHECK_FN(current)) {
|
||||
aFunction = new CurrentFunctionCall(this);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (GENERATE_ID_FN.isEqual(name)) {
|
||||
return new GenerateIdFunctionCall();
|
||||
if (CHECK_FN(unparsedEntityUri)) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
else if (SYSTEM_PROPERTY_FN.isEqual(name)) {
|
||||
return new SystemPropertyFunctionCall();
|
||||
if (CHECK_FN(generateId)) {
|
||||
aFunction = new GenerateIdFunctionCall();
|
||||
return NS_OK;
|
||||
}
|
||||
else if (ELEMENT_AVAILABLE_FN.isEqual(name)) {
|
||||
return new ElementAvailableFunctionCall();
|
||||
if (CHECK_FN(systemProperty)) {
|
||||
aFunction = new SystemPropertyFunctionCall(aElem);
|
||||
return NS_OK;
|
||||
}
|
||||
else if (FUNCTION_AVAILABLE_FN.isEqual(name)) {
|
||||
return new FunctionAvailableFunctionCall();
|
||||
if (CHECK_FN(elementAvailable)) {
|
||||
aFunction = new ElementAvailableFunctionCall(aElem);
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
err = "invalid function call: ";
|
||||
err.append(name);
|
||||
if (CHECK_FN(functionAvailable)) {
|
||||
aFunction = new FunctionAvailableFunctionCall();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return new ErrorFunctionCall(err);
|
||||
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
} //-- resolveFunctionCall
|
||||
|
||||
//-------------------/
|
||||
|
@ -1057,9 +1071,6 @@ void ProcessorState::initialize()
|
|||
}
|
||||
if (xslDocument) {
|
||||
loadedDocuments.put(xslDocument->getBaseURI(), xslDocument);
|
||||
// XXX hackarond to get namespacehandling in a little better shape
|
||||
// we won't need to do this once we resolve namespaces during parsing
|
||||
mXPathParseContext = xslDocument->getDocumentElement();
|
||||
}
|
||||
|
||||
// make sure all keys are deleted
|
||||
|
@ -1105,3 +1116,34 @@ ProcessorState::ImportFrame::~ImportFrame()
|
|||
}
|
||||
delete templKeys;
|
||||
}
|
||||
|
||||
/*
|
||||
* txPSParseContext
|
||||
* txIParseContext used by ProcessorState internally
|
||||
*/
|
||||
|
||||
nsresult txPSParseContext::resolveNamespacePrefix(txAtom* aPrefix,
|
||||
PRInt32& aID)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!aPrefix || aPrefix == txXMLAtoms::_empty) {
|
||||
// default namespace is not forwarded to xpath
|
||||
NS_ASSERTION(0, "caller should handle default namespace ''");
|
||||
aID = kNameSpaceID_None;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
aID = mStyle->lookupNamespaceID(aPrefix);
|
||||
return (aID != kNameSpaceID_Unknown) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult txPSParseContext::resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction)
|
||||
{
|
||||
return mPS->resolveFunctionCall(aName, aID, mStyle, aFunction);
|
||||
}
|
||||
|
||||
void txPSParseContext::receiveError(const String& aMsg, nsresult aRes)
|
||||
{
|
||||
mPS->receiveError(aMsg, aRes);
|
||||
}
|
||||
|
|
|
@ -33,11 +33,12 @@
|
|||
#include "Stack.h"
|
||||
#include "ErrorObserver.h"
|
||||
#include "NamedMap.h"
|
||||
#include "ExprParser.h"
|
||||
#include "txPatternParser.h"
|
||||
#include "Expr.h"
|
||||
#include "StringList.h"
|
||||
#include "txOutputFormat.h"
|
||||
#include "Map.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
class txXSLKey;
|
||||
class txDecimalFormat;
|
||||
|
@ -45,7 +46,7 @@ class txDecimalFormat;
|
|||
/**
|
||||
* Class used for keeping the current state of the XSL Processor
|
||||
**/
|
||||
class ProcessorState : public ContextState {
|
||||
class ProcessorState : public txIMatchContext {
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -145,14 +146,6 @@ public:
|
|||
*/
|
||||
Element* getNamedTemplate(String& aName);
|
||||
|
||||
/**
|
||||
* Returns the NodeStack which keeps track of where we are in the
|
||||
* result tree
|
||||
* @return the NodeStack which keeps track of where we are in the
|
||||
* result tree
|
||||
**/
|
||||
NodeStack* getNodeStack();
|
||||
|
||||
/**
|
||||
* Returns the OutputFormat which contains information on how
|
||||
* to serialize the output. I will be removing this soon, when
|
||||
|
@ -176,7 +169,7 @@ public:
|
|||
};
|
||||
|
||||
Expr* getExpr(Element* aElem, ExprAttr aAttr);
|
||||
Pattern* getPattern(Element* aElem, PatternAttr aAttr);
|
||||
txPattern* getPattern(Element* aElem, PatternAttr aAttr);
|
||||
|
||||
/**
|
||||
* Returns a pointer to the result document
|
||||
|
@ -263,28 +256,17 @@ public:
|
|||
**/
|
||||
void preserveSpace(String& names);
|
||||
|
||||
/**
|
||||
* Removes and returns the current node being processed from the stack
|
||||
* @return the current node
|
||||
**/
|
||||
Node* popCurrentNode();
|
||||
|
||||
void processAttrValueTemplate(const String& aAttValue,
|
||||
Node* aContext,
|
||||
Element* aContext,
|
||||
String& aResult);
|
||||
|
||||
/**
|
||||
* Sets the given source node as the "current node" being processed
|
||||
* @param node the source node currently being processed
|
||||
**/
|
||||
void pushCurrentNode(Node* node);
|
||||
|
||||
/**
|
||||
* Adds the set of names to the Whitespace stripping handling list.
|
||||
* xsl:strip-space calls this with MB_TRUE, xsl:preserve-space
|
||||
* with MB_FALSE
|
||||
* aElement is used to resolve QNames
|
||||
*/
|
||||
void shouldStripSpace(String& aNames,
|
||||
void shouldStripSpace(String& aNames, Element* aElement,
|
||||
MBool aShouldStrip,
|
||||
ImportFrame* aImportFrame);
|
||||
|
||||
|
@ -310,65 +292,62 @@ public:
|
|||
**/
|
||||
txDecimalFormat* getDecimalFormat(String& name);
|
||||
|
||||
//-------------------------------------/
|
||||
//- Virtual Methods from ContextState -/
|
||||
//-------------------------------------/
|
||||
/*
|
||||
* Virtual methods from txIEvalContext
|
||||
*/
|
||||
|
||||
TX_DECL_MATCH_CONTEXT;
|
||||
|
||||
/*
|
||||
* Set the current txIEvalContext and get the prior one
|
||||
*/
|
||||
txIEvalContext* setEvalContext(txIEvalContext* aEContext)
|
||||
{
|
||||
txIEvalContext* tmp = mEvalContext;
|
||||
mEvalContext = aEContext;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the current txIEvalContext
|
||||
*/
|
||||
txIEvalContext* getEvalContext()
|
||||
{
|
||||
return mEvalContext;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* More other functions
|
||||
*/
|
||||
void receiveError(String& errorMessage)
|
||||
{
|
||||
receiveError(errorMessage, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of a given variable binding within the current scope
|
||||
* @param the name to which the desired variable value has been bound
|
||||
* @return the ExprResult which has been bound to the variable with
|
||||
* the given name
|
||||
**/
|
||||
virtual ExprResult* getVariable(String& name);
|
||||
|
||||
/**
|
||||
* Returns the Stack of context NodeSets
|
||||
* @return the Stack of context NodeSets
|
||||
**/
|
||||
virtual Stack* getNodeSetStack();
|
||||
|
||||
/**
|
||||
* Determines if the given XML node allows Whitespace stripping
|
||||
**/
|
||||
virtual MBool isStripSpaceAllowed(Node* node);
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error, with default
|
||||
* level of NORMAL
|
||||
**/
|
||||
virtual void recieveError(String& errorMessage);
|
||||
|
||||
/**
|
||||
* Notifies this Error observer of a new error using the given error level
|
||||
**/
|
||||
virtual void recieveError(String& errorMessage, ErrorLevel level);
|
||||
|
||||
/**
|
||||
* Returns a call to the function that has the given name.
|
||||
* This method is used for XPath Extension Functions.
|
||||
* Returns a FunctionCall which has the given name.
|
||||
* @return the FunctionCall for the function with the given name.
|
||||
**/
|
||||
virtual FunctionCall* resolveFunctionCall(const String& name);
|
||||
|
||||
/**
|
||||
* Returns the namespace URI for the given namespace prefix. This method
|
||||
* should only be called to get a namespace declared within the
|
||||
* context (ie. the stylesheet).
|
||||
**/
|
||||
void getNameSpaceURIFromPrefix(const String& aPrefix, String& aNamespaceURI);
|
||||
nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
||||
Element* aElem, FunctionCall*& aFunction);
|
||||
|
||||
private:
|
||||
|
||||
enum XMLSpaceMode {STRIP = 0, DEFAULT, PRESERVE};
|
||||
|
||||
struct MatchableTemplate {
|
||||
class MatchableTemplate {
|
||||
public:
|
||||
MatchableTemplate(Node* aTemplate, txPattern* aPattern,
|
||||
double aPriority)
|
||||
: mTemplate(aTemplate), mMatch(aPattern), mPriority(aPriority)
|
||||
{
|
||||
}
|
||||
Node* mTemplate;
|
||||
Pattern* mMatch;
|
||||
txPattern* mMatch;
|
||||
double mPriority;
|
||||
};
|
||||
|
||||
NodeStack currentNodeStack;
|
||||
|
||||
/**
|
||||
* The list of ErrorObservers registered with this ProcessorState
|
||||
**/
|
||||
|
@ -423,18 +402,20 @@ private:
|
|||
*/
|
||||
Map mPatternHashes[2];
|
||||
|
||||
/*
|
||||
* Current txIEvalContext*
|
||||
*/
|
||||
txIEvalContext* mEvalContext;
|
||||
|
||||
/*
|
||||
* Current template rule
|
||||
*/
|
||||
TemplateRule* mCurrentTemplateRule;
|
||||
|
||||
Element* mXPathParseContext;
|
||||
Stack nodeSetStack;
|
||||
Document* mSourceDocument;
|
||||
Document* xslDocument;
|
||||
Document* resultDocument;
|
||||
Stack variableSets;
|
||||
ExprParser exprParser;
|
||||
|
||||
/**
|
||||
* Returns the closest xml:space value for the given node
|
||||
|
@ -454,11 +435,15 @@ private:
|
|||
**/
|
||||
class txNameTestItem {
|
||||
public:
|
||||
txNameTestItem(String& aName, MBool stripSpace):
|
||||
mNameTest(aName),mStrips(stripSpace) {}
|
||||
txNameTestItem(txAtom* aPrefix, txAtom* aLocalName, PRUint32 aNSID,
|
||||
MBool stripSpace)
|
||||
: mNameTest(aPrefix, aLocalName, aNSID, Node::ELEMENT_NODE),
|
||||
mStrips(stripSpace)
|
||||
{
|
||||
}
|
||||
|
||||
MBool matches(Node* aNode, ContextState* aCS) {
|
||||
return mNameTest.matches(aNode, 0, aCS);
|
||||
MBool matches(Node* aNode, txIMatchContext* aContext) {
|
||||
return mNameTest.matches(aNode, aContext);
|
||||
}
|
||||
|
||||
MBool stripsSpace() {
|
||||
|
@ -466,13 +451,39 @@ public:
|
|||
}
|
||||
|
||||
double getDefaultPriority() {
|
||||
return mNameTest.getDefaultPriority(0, 0, 0);
|
||||
return mNameTest.getDefaultPriority();
|
||||
}
|
||||
|
||||
protected:
|
||||
ElementExpr mNameTest;
|
||||
txNameTest mNameTest;
|
||||
MBool mStrips;
|
||||
};
|
||||
|
||||
/*
|
||||
* txPSParseContext
|
||||
* a txIParseContext forwarding all but resolveNamespacePrefix
|
||||
* to a ProcessorState
|
||||
*/
|
||||
class txPSParseContext : public txIParseContext {
|
||||
public:
|
||||
txPSParseContext(ProcessorState* aPS, Element* aStyleNode)
|
||||
: mPS(aPS), mStyle(aStyleNode)
|
||||
{
|
||||
}
|
||||
|
||||
~txPSParseContext()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult resolveNamespacePrefix(txAtom* aPrefix, PRInt32& aID);
|
||||
nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
||||
FunctionCall*& aFunction);
|
||||
void receiveError(const String& aMsg, nsresult aRes);
|
||||
|
||||
protected:
|
||||
ProcessorState* mPS;
|
||||
Element* mStyle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
#include "txAtoms.h"
|
||||
#include "TxLog.h"
|
||||
#include "txRtfHandler.h"
|
||||
#include "txNodeSetContext.h"
|
||||
#include "txSingleNodeContext.h"
|
||||
#ifndef TX_EXE
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
@ -144,9 +146,10 @@ XSLTProcessor::XSLTProcessor() : mOutputHandler(0),
|
|||
xslTypes.put(WITH_PARAM, new XSLType(XSLType::WITH_PARAM));
|
||||
|
||||
// Create default expressions
|
||||
ExprParser parser;
|
||||
String node("node()");
|
||||
mNodeExpr = parser.createExpr(node);
|
||||
|
||||
// "node()"
|
||||
txNodeTest* nt = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
mNodeExpr = new LocationStep(nt, LocationStep::CHILD_AXIS);
|
||||
|
||||
} //-- XSLTProcessor
|
||||
|
||||
|
@ -351,7 +354,7 @@ Document* XSLTProcessor::process
|
|||
if (!xmlDoc) {
|
||||
String err("error reading XML document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
return 0;
|
||||
}
|
||||
//-- Read in XSL document
|
||||
|
@ -359,7 +362,7 @@ Document* XSLTProcessor::process
|
|||
if (!xslDoc) {
|
||||
String err("error reading XSL stylesheet document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
delete xmlDoc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -386,7 +389,7 @@ Document* XSLTProcessor::process(istream& xmlInput, String& xmlFilename) {
|
|||
if (!xmlDoc) {
|
||||
String err("error reading XML document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
return 0;
|
||||
}
|
||||
//-- Read in XSL document
|
||||
|
@ -402,7 +405,7 @@ Document* XSLTProcessor::process(istream& xmlInput, String& xmlFilename) {
|
|||
if (!xslDoc) {
|
||||
String err("error reading XSL stylesheet document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
delete xmlDoc;
|
||||
return 0;
|
||||
}
|
||||
|
@ -542,7 +545,7 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
err.append("\"");
|
||||
}
|
||||
err.append(" decimal format for xsl:decimal-format");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -552,7 +555,8 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
element->getAttr(txXSLTAtoms::name, kNameSpaceID_None,
|
||||
name);
|
||||
if (name.isEmpty()) {
|
||||
notifyError("missing required name attribute for xsl:param");
|
||||
String err("missing required name attribute for xsl:param");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -563,7 +567,8 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
}
|
||||
case XSLType::IMPORT :
|
||||
{
|
||||
notifyError("xsl:import only allowed at top of stylesheet");
|
||||
String err("xsl:import only allowed at top of stylesheet");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
case XSLType::INCLUDE :
|
||||
|
@ -586,7 +591,7 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
String err("error adding key '");
|
||||
err.append(name);
|
||||
err.append("'");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -679,7 +684,8 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
element->getAttr(txXSLTAtoms::name, kNameSpaceID_None,
|
||||
name);
|
||||
if (name.isEmpty()) {
|
||||
notifyError("missing required name attribute for xsl:variable");
|
||||
String err("missing required name attribute for xsl:variable");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
ExprResult* exprResult = processVariable(aSource, element, aPs);
|
||||
|
@ -694,10 +700,10 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
//-- add error to ErrorObserver
|
||||
String err("missing required 'elements' attribute for ");
|
||||
err.append("xsl:preserve-space");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
else {
|
||||
aPs->shouldStripSpace(elements,
|
||||
aPs->shouldStripSpace(elements, element,
|
||||
MB_FALSE,
|
||||
currentFrame);
|
||||
}
|
||||
|
@ -711,10 +717,10 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
//-- add error to ErrorObserver
|
||||
String err("missing required 'elements' attribute for ");
|
||||
err.append("xsl:strip-space");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
else {
|
||||
aPs->shouldStripSpace(elements,
|
||||
aPs->shouldStripSpace(elements, element,
|
||||
MB_TRUE,
|
||||
currentFrame);
|
||||
}
|
||||
|
@ -754,7 +760,7 @@ void XSLTProcessor::processInclude(String& aHref,
|
|||
if (((String*)iter->next())->isEqual(aHref)) {
|
||||
String err("Stylesheet includes itself. URI: ");
|
||||
err.append(aHref);
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
delete iter;
|
||||
return;
|
||||
}
|
||||
|
@ -767,7 +773,7 @@ void XSLTProcessor::processInclude(String& aHref,
|
|||
if (!stylesheet) {
|
||||
String err("Unable to load included stylesheet ");
|
||||
err.append(aHref);
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
aPs->getEnteredStylesheets()->pop();
|
||||
return;
|
||||
}
|
||||
|
@ -785,7 +791,7 @@ void XSLTProcessor::processInclude(String& aHref,
|
|||
default:
|
||||
// This should never happen
|
||||
String err("Unsupported fragment identifier");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -823,10 +829,9 @@ Document* XSLTProcessor::process(Document& xmlDocument,
|
|||
while (iter.hasNext())
|
||||
ps.addErrorObserver(*(ErrorObserver*)iter.next());
|
||||
|
||||
NodeSet nodeSet(&aXMLDocument);
|
||||
ps.pushCurrentNode(&aXMLDocument);
|
||||
ps.getNodeSetStack()->push(&nodeSet);
|
||||
|
||||
txSingleNodeContext evalContext(&aXMLDocument, &ps);
|
||||
ps.setEvalContext(&evalContext);
|
||||
|
||||
// Index templates and process top level xsl elements
|
||||
txListIterator importFrame(ps.getImportFrames());
|
||||
importFrame.addAfter(new ProcessorState::ImportFrame(0));
|
||||
|
@ -882,9 +887,8 @@ void XSLTProcessor::process(Document& aXMLDocument,
|
|||
while (iter.hasNext())
|
||||
ps.addErrorObserver(*(ErrorObserver*)iter.next());
|
||||
|
||||
NodeSet nodeSet(&aXMLDocument);
|
||||
ps.pushCurrentNode(&aXMLDocument);
|
||||
ps.getNodeSetStack()->push(&nodeSet);
|
||||
txSingleNodeContext evalContext(&aXMLDocument, &ps);
|
||||
ps.setEvalContext(&evalContext);
|
||||
|
||||
// Index templates and process top level xsl elements
|
||||
txListIterator importFrame(ps.getImportFrames());
|
||||
|
@ -926,7 +930,7 @@ void XSLTProcessor::process
|
|||
if (!xmlDoc) {
|
||||
String err("error reading XML document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
return;
|
||||
}
|
||||
//-- Read in XSL document
|
||||
|
@ -942,7 +946,7 @@ void XSLTProcessor::process
|
|||
if (!xslDoc) {
|
||||
String err("error reading XSL stylesheet document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
delete xmlDoc;
|
||||
return;
|
||||
}
|
||||
|
@ -954,7 +958,7 @@ void XSLTProcessor::process
|
|||
stylesheet = xslDoc->getElementById(frag);
|
||||
if (!stylesheet) {
|
||||
String err("unable to get fragment");
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
delete xmlDoc;
|
||||
delete xslDoc;
|
||||
return;
|
||||
|
@ -987,7 +991,7 @@ void XSLTProcessor::process
|
|||
if (!xmlDoc) {
|
||||
String err("error reading XML document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
return;
|
||||
}
|
||||
//-- read in XSL Document
|
||||
|
@ -995,7 +999,7 @@ void XSLTProcessor::process
|
|||
if (!xslDoc) {
|
||||
String err("error reading XSL stylesheet document: ");
|
||||
err.append(xmlParser.getErrorString());
|
||||
notifyError(err, ErrorObserver::FATAL);
|
||||
cerr << err << endl;
|
||||
delete xmlDoc;
|
||||
return;
|
||||
}
|
||||
|
@ -1031,7 +1035,7 @@ void XSLTProcessor::bindVariable
|
|||
String err("cannot rebind variables: ");
|
||||
err.append(name);
|
||||
err.append(" already exists in this scope.");
|
||||
notifyError(err);
|
||||
ps->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1068,39 +1072,6 @@ short XSLTProcessor::getElementType(Element* aElement, ProcessorState* aPs)
|
|||
return xslType->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all registered ErrorObservers of the given error
|
||||
**/
|
||||
void XSLTProcessor::notifyError(const char* errorMessage) {
|
||||
String err(errorMessage);
|
||||
notifyError(err, ErrorObserver::NORMAL);
|
||||
} //-- notifyError
|
||||
|
||||
/**
|
||||
* Notifies all registered ErrorObservers of the given error
|
||||
**/
|
||||
void XSLTProcessor::notifyError(String& errorMessage) {
|
||||
notifyError(errorMessage, ErrorObserver::NORMAL);
|
||||
} //-- notifyError
|
||||
|
||||
/**
|
||||
* Notifies all registered ErrorObservers of the given error
|
||||
**/
|
||||
void XSLTProcessor::notifyError(String& errorMessage, ErrorObserver::ErrorLevel level) {
|
||||
ListIterator* iter = errorObservers.iterator();
|
||||
|
||||
//-- send fatal errors to default observer if no error obersvers
|
||||
//-- have been registered
|
||||
if ((!iter->hasNext()) && (level == ErrorObserver::FATAL)) {
|
||||
fatalObserver.recieveError(errorMessage, level);
|
||||
}
|
||||
while ( iter->hasNext() ) {
|
||||
ErrorObserver* observer = (ErrorObserver*)iter->next();
|
||||
observer->recieveError(errorMessage, level);
|
||||
}
|
||||
delete iter;
|
||||
} //-- notifyError
|
||||
|
||||
void XSLTProcessor::process(Node* node,
|
||||
const String& mode,
|
||||
ProcessorState* ps) {
|
||||
|
@ -1150,7 +1121,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
curr = aPs->getCurrentTemplateRule();
|
||||
if (!curr) {
|
||||
String err("apply-imports not allowed here");
|
||||
aPs->recieveError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1174,16 +1145,13 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (!expr)
|
||||
break;
|
||||
|
||||
ExprResult* exprResult = expr->evaluate(aNode, aPs);
|
||||
ExprResult* exprResult = expr->evaluate(aPs->getEvalContext());
|
||||
if (!exprResult)
|
||||
break;
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* nodeSet = (NodeSet*)exprResult;
|
||||
|
||||
//-- push nodeSet onto context stack
|
||||
aPs->getNodeSetStack()->push(nodeSet);
|
||||
|
||||
// Look for xsl:sort elements
|
||||
txNodeSorter sorter(aPs);
|
||||
Node* child = actionElement->getFirstChild();
|
||||
|
@ -1202,22 +1170,27 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
String mode;
|
||||
actionElement->getAttr(txXSLTAtoms::mode,
|
||||
kNameSpaceID_None, mode);
|
||||
for (int i = 0; i < nodeSet->size(); i++) {
|
||||
|
||||
txNodeSetContext evalContext(nodeSet, aPs);
|
||||
txIEvalContext* priorEC =
|
||||
aPs->setEvalContext(&evalContext);
|
||||
while (evalContext.hasNext()) {
|
||||
evalContext.next();
|
||||
ProcessorState::ImportFrame *frame;
|
||||
Node* currNode = nodeSet->get(i);
|
||||
Node* currNode = evalContext.getContextNode();
|
||||
Node* xslTemplate;
|
||||
xslTemplate = aPs->findTemplate(currNode, mode, &frame);
|
||||
processMatchedTemplate(xslTemplate, currNode,
|
||||
actualParams, mode, frame, aPs);
|
||||
}
|
||||
|
||||
//-- remove nodeSet from context stack
|
||||
aPs->getNodeSetStack()->pop();
|
||||
aPs->setEvalContext(priorEC);
|
||||
|
||||
delete actualParams;
|
||||
}
|
||||
else {
|
||||
notifyError("error processing apply-templates");
|
||||
String err("error processing apply-templates");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
//-- clean up
|
||||
delete exprResult;
|
||||
|
@ -1229,20 +1202,21 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
String nameAttr;
|
||||
if (!actionElement->getAttr(txXSLTAtoms::name,
|
||||
kNameSpaceID_None, nameAttr)) {
|
||||
notifyError("missing required name attribute for xsl:attribute");
|
||||
String err("missing required name attribute for xsl:attribute");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
// Process name as an AttributeValueTemplate
|
||||
String name;
|
||||
aPs->processAttrValueTemplate(nameAttr, aNode, name);
|
||||
aPs->processAttrValueTemplate(nameAttr, actionElement, name);
|
||||
|
||||
// Check name validity (must be valid QName and not xmlns)
|
||||
if (!XMLUtils::isValidQName(name)) {
|
||||
String err("error processing xsl:attribute, ");
|
||||
err.append(name);
|
||||
err.append(" is not a valid QName.");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1250,7 +1224,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (nameAtom == txXMLAtoms::xmlns) {
|
||||
TX_RELEASE_ATOM(nameAtom);
|
||||
String err("error processing xsl:attribute, name is xmlns.");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
TX_IF_RELEASE_ATOM(nameAtom);
|
||||
|
@ -1262,7 +1236,8 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (actionElement->getAttr(txXSLTAtoms::_namespace, kNameSpaceID_None,
|
||||
resultNs)) {
|
||||
String nsURI;
|
||||
aPs->processAttrValueTemplate(resultNs, aNode, nsURI);
|
||||
aPs->processAttrValueTemplate(resultNs, actionElement,
|
||||
nsURI);
|
||||
resultNsID = resultDoc->namespaceURIToID(nsURI);
|
||||
}
|
||||
else {
|
||||
|
@ -1314,7 +1289,8 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
}
|
||||
}
|
||||
else {
|
||||
notifyError("missing required name attribute for xsl:call-template");
|
||||
String err("missing required name attribute for xsl:call-template");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1335,7 +1311,8 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (!expr)
|
||||
break;
|
||||
|
||||
ExprResult* result = expr->evaluate(aNode, aPs);
|
||||
ExprResult* result = expr->evaluate
|
||||
(aPs->getEvalContext());
|
||||
if (result && result->booleanValue()) {
|
||||
processChildren(aNode, xslTemplate, aPs);
|
||||
caseFound = MB_TRUE;
|
||||
|
@ -1384,7 +1361,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (!expr)
|
||||
break;
|
||||
|
||||
ExprResult* exprResult = expr->evaluate(aNode, aPs);
|
||||
ExprResult* exprResult = expr->evaluate(aPs->getEvalContext());
|
||||
xslCopyOf(exprResult, aPs);
|
||||
delete exprResult;
|
||||
break;
|
||||
|
@ -1396,20 +1373,21 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
String nameAttr;
|
||||
if (!actionElement->getAttr(txXSLTAtoms::name,
|
||||
kNameSpaceID_None, nameAttr)) {
|
||||
notifyError("missing required name attribute for xsl:element");
|
||||
String err("missing required name attribute for xsl:element");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
// Process name as an AttributeValueTemplate
|
||||
String name;
|
||||
aPs->processAttrValueTemplate(nameAttr, aNode, name);
|
||||
aPs->processAttrValueTemplate(nameAttr, actionElement, name);
|
||||
|
||||
// Check name validity (must be valid QName and not xmlns)
|
||||
if (!XMLUtils::isValidQName(name)) {
|
||||
String err("error processing xsl:element, '");
|
||||
err.append(name);
|
||||
err.append("' is not a valid QName.");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
// XXX We should processChildren without creating attributes or
|
||||
// namespace nodes.
|
||||
break;
|
||||
|
@ -1421,7 +1399,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
PRInt32 resultNsID;
|
||||
if (actionElement->getAttr(txXSLTAtoms::_namespace, kNameSpaceID_None, resultNs)) {
|
||||
String nsURI;
|
||||
aPs->processAttrValueTemplate(resultNs, aNode, nsURI);
|
||||
aPs->processAttrValueTemplate(resultNs, actionElement, nsURI);
|
||||
if (nsURI.isEmpty())
|
||||
resultNsID = kNameSpaceID_None;
|
||||
else
|
||||
|
@ -1439,7 +1417,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
String err("error processing xsl:element, can't resolve prefix on'");
|
||||
err.append(name);
|
||||
err.append("'.");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
// XXX We should processChildren without creating attributes or
|
||||
// namespace nodes.
|
||||
break;
|
||||
|
@ -1459,15 +1437,15 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (!expr)
|
||||
break;
|
||||
|
||||
ExprResult* exprResult = expr->evaluate(aNode, aPs);
|
||||
ExprResult* exprResult = expr->evaluate(aPs->getEvalContext());
|
||||
if (!exprResult)
|
||||
break;
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* nodeSet = (NodeSet*)exprResult;
|
||||
|
||||
//-- push nodeSet onto context stack
|
||||
aPs->getNodeSetStack()->push(nodeSet);
|
||||
txNodeSetContext evalContext(nodeSet, aPs);
|
||||
txIEvalContext* priorEC =
|
||||
aPs->setEvalContext(&evalContext);
|
||||
|
||||
// Look for xsl:sort elements
|
||||
txNodeSorter sorter(aPs);
|
||||
|
@ -1498,20 +1476,18 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
oldTemplate = aPs->getCurrentTemplateRule();
|
||||
aPs->setCurrentTemplateRule(0);
|
||||
|
||||
for (int i = 0; i < nodeSet->size(); i++) {
|
||||
Node* currNode = nodeSet->get(i);
|
||||
aPs->pushCurrentNode(currNode);
|
||||
while (evalContext.hasNext()) {
|
||||
evalContext.next();
|
||||
Node* currNode = evalContext.getContextNode();
|
||||
processChildren(currNode, actionElement, aPs);
|
||||
aPs->popCurrentNode();
|
||||
}
|
||||
|
||||
aPs->setCurrentTemplateRule(oldTemplate);
|
||||
|
||||
// Remove nodeSet from context stack
|
||||
aPs->getNodeSetStack()->pop();
|
||||
aPs->setEvalContext(priorEC);
|
||||
}
|
||||
else {
|
||||
notifyError("error processing for-each");
|
||||
String err("error processing for-each");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
//-- clean up exprResult
|
||||
delete exprResult;
|
||||
|
@ -1524,7 +1500,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (!expr)
|
||||
break;
|
||||
|
||||
ExprResult* exprResult = expr->evaluate(aNode, aPs);
|
||||
ExprResult* exprResult = expr->evaluate(aPs->getEvalContext());
|
||||
if (!exprResult)
|
||||
break;
|
||||
|
||||
|
@ -1560,7 +1536,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
case XSLType::NUMBER:
|
||||
{
|
||||
String result;
|
||||
Numbering::doNumbering(actionElement, result, aNode, aPs);
|
||||
Numbering::doNumbering(actionElement, result, aPs);
|
||||
NS_ASSERTION(mResultHandler, "mResultHandler must not be NULL!");
|
||||
mResultHandler->characters(result);
|
||||
break;
|
||||
|
@ -1579,13 +1555,13 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
kNameSpaceID_None, nameAttr)) {
|
||||
String err("missing required name attribute for xsl:");
|
||||
err.append(PROC_INST);
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
// Process name as an AttributeValueTemplate
|
||||
String name;
|
||||
aPs->processAttrValueTemplate(nameAttr, aNode, name);
|
||||
aPs->processAttrValueTemplate(nameAttr, actionElement, name);
|
||||
|
||||
// Check name validity (must be valid NCName and a PITarget)
|
||||
// XXX Need to check for NCName and PITarget
|
||||
|
@ -1595,7 +1571,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
err.append(", '");
|
||||
err.append(name);
|
||||
err.append("' is not a valid QName.");
|
||||
notifyError(err);
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
// Compute value
|
||||
|
@ -1640,10 +1616,11 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
if (!expr)
|
||||
break;
|
||||
|
||||
ExprResult* exprResult = expr->evaluate(aNode, aPs);
|
||||
ExprResult* exprResult = expr->evaluate(aPs->getEvalContext());
|
||||
String value;
|
||||
if (!exprResult) {
|
||||
notifyError("null ExprResult");
|
||||
String err("null ExprResult");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
exprResult->stringValue(value);
|
||||
|
@ -1670,7 +1647,8 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
String name;
|
||||
if (!actionElement->getAttr(txXSLTAtoms::name,
|
||||
kNameSpaceID_None, name)) {
|
||||
notifyError("missing required name attribute for xsl:variable");
|
||||
String err("missing required name attribute for xsl:variable");
|
||||
aPs->receiveError(err, NS_ERROR_FAILURE);
|
||||
break;
|
||||
}
|
||||
ExprResult* exprResult = processVariable(aNode, actionElement, aPs);
|
||||
|
@ -1699,7 +1677,7 @@ void XSLTProcessor::processAction(Node* aNode,
|
|||
continue;
|
||||
// Process Attribute Value Templates
|
||||
String value;
|
||||
aPs->processAttrValueTemplate(attr->getValue(), aNode, value);
|
||||
aPs->processAttrValueTemplate(attr->getValue(), actionElement, value);
|
||||
NS_ASSERTION(mResultHandler, "mResultHandler must not be NULL!");
|
||||
mResultHandler->attribute(attr->getName(), attr->getNamespaceID(), value);
|
||||
}
|
||||
|
@ -1798,7 +1776,8 @@ NamedMap* XSLTProcessor::processParameters(Element* xslAction, Node* context, Pr
|
|||
String name;
|
||||
if (!action->getAttr(txXSLTAtoms::name,
|
||||
kNameSpaceID_None, name)) {
|
||||
notifyError("missing required name attribute for xsl:with-param");
|
||||
String err("missing required name attribute for xsl:with-param");
|
||||
ps->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
else {
|
||||
ExprResult* exprResult = processVariable(context, action, ps);
|
||||
|
@ -1807,7 +1786,7 @@ NamedMap* XSLTProcessor::processParameters(Element* xslAction, Node* context, Pr
|
|||
String err("value for parameter '");
|
||||
err.append(name);
|
||||
err.append("' specified more than once.");
|
||||
notifyError(err);
|
||||
ps->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
else {
|
||||
VariableBinding* binding = new VariableBinding(name, exprResult);
|
||||
|
@ -1925,9 +1904,7 @@ void XSLTProcessor::processMatchedTemplate(Node* aXslTemplate,
|
|||
newTemplate.mParams = aParams;
|
||||
aPs->setCurrentTemplateRule(&newTemplate);
|
||||
|
||||
aPs->pushCurrentNode(aNode);
|
||||
processTemplate(aNode, aXslTemplate, aPs, aParams);
|
||||
aPs->popCurrentNode();
|
||||
|
||||
aPs->setCurrentTemplateRule(oldTemplate);
|
||||
}
|
||||
|
@ -1956,28 +1933,29 @@ void XSLTProcessor::processDefaultTemplate(Node* node,
|
|||
if (!mNodeExpr)
|
||||
break;
|
||||
|
||||
ExprResult* exprResult = mNodeExpr->evaluate(node, ps);
|
||||
ExprResult* exprResult = mNodeExpr->evaluate(ps->getEvalContext());
|
||||
if (!exprResult ||
|
||||
exprResult->getResultType() != ExprResult::NODESET) {
|
||||
notifyError("None-nodeset returned while processing default template");
|
||||
String err("None-nodeset returned while processing default template");
|
||||
ps->receiveError(err, NS_ERROR_FAILURE);
|
||||
delete exprResult;
|
||||
return;
|
||||
}
|
||||
|
||||
NodeSet* nodeSet = (NodeSet*)exprResult;
|
||||
txNodeSetContext evalContext(nodeSet, ps);
|
||||
txIEvalContext* priorEC = ps->setEvalContext(&evalContext);
|
||||
|
||||
//-- push nodeSet onto context stack
|
||||
ps->getNodeSetStack()->push(nodeSet);
|
||||
for (int i = 0; i < nodeSet->size(); i++) {
|
||||
Node* currNode = nodeSet->get(i);
|
||||
while (evalContext.hasNext()) {
|
||||
evalContext.next();
|
||||
Node* currNode = evalContext.getContextNode();
|
||||
|
||||
ProcessorState::ImportFrame *frame;
|
||||
Node* xslTemplate = ps->findTemplate(currNode, mode, &frame);
|
||||
processMatchedTemplate(xslTemplate, currNode, 0, mode, frame,
|
||||
ps);
|
||||
}
|
||||
//-- remove nodeSet from context stack
|
||||
ps->getNodeSetStack()->pop();
|
||||
ps->setEvalContext(priorEC);
|
||||
delete exprResult;
|
||||
break;
|
||||
}
|
||||
|
@ -2022,7 +2000,8 @@ void XSLTProcessor::processTemplateParams
|
|||
String name;
|
||||
if (!action->getAttr(txXSLTAtoms::name,
|
||||
kNameSpaceID_None, name)) {
|
||||
notifyError("missing required name attribute for xsl:param");
|
||||
String err("missing required name attribute for xsl:param");
|
||||
ps->receiveError(err, NS_ERROR_FAILURE);
|
||||
}
|
||||
else {
|
||||
VariableBinding* binding = 0;
|
||||
|
@ -2075,7 +2054,7 @@ ExprResult* XSLTProcessor::processVariable
|
|||
Expr* expr = ps->getExpr(xslVariable, ProcessorState::SelectAttr);
|
||||
if (!expr)
|
||||
return new StringResult("unable to process variable");
|
||||
return expr->evaluate(node, ps);
|
||||
return expr->evaluate(ps->getEvalContext());
|
||||
}
|
||||
else if (xslVariable->hasChildNodes()) {
|
||||
txResultTreeFragment* rtf = new txResultTreeFragment();
|
||||
|
@ -2418,10 +2397,9 @@ XSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
|
|||
|
||||
// XXX Need to add error observers
|
||||
|
||||
// Set current node and nodeset.
|
||||
NodeSet nodeSet(&sourceDocument);
|
||||
ps.pushCurrentNode(&sourceDocument);
|
||||
ps.getNodeSetStack()->push(&nodeSet);
|
||||
// Set current txIEvalContext
|
||||
txSingleNodeContext evalContext(&sourceDocument, &ps);
|
||||
ps.setEvalContext(&evalContext);
|
||||
|
||||
// Index templates and process top level xsl elements
|
||||
ListIterator importFrame(ps.getImportFrames());
|
||||
|
|
|
@ -275,21 +275,6 @@ private:
|
|||
**/
|
||||
short getElementType(Element* aElement, ProcessorState* aPs);
|
||||
|
||||
/**
|
||||
* Notifies all registered ErrorObservers of the given error
|
||||
**/
|
||||
void notifyError(const char* errorMessage);
|
||||
|
||||
/**
|
||||
* Notifies all registered ErrorObservers of the given error
|
||||
**/
|
||||
void notifyError(String& errorMessage);
|
||||
|
||||
/**
|
||||
* Notifies all registered ErrorObservers of the given error
|
||||
**/
|
||||
void notifyError(String& errorMessage, ErrorObserver::ErrorLevel level);
|
||||
|
||||
#ifdef TX_EXE
|
||||
/**
|
||||
* Parses the contents of data, and returns the type and href psuedo attributes
|
||||
|
|
|
@ -8,22 +8,19 @@
|
|||
/**
|
||||
* Creates a new current function call
|
||||
**/
|
||||
CurrentFunctionCall::CurrentFunctionCall(ProcessorState* ps) :
|
||||
FunctionCall(CURRENT_FN)
|
||||
CurrentFunctionCall::CurrentFunctionCall(ProcessorState* aPs)
|
||||
: FunctionCall(CURRENT_FN), mPs(aPs)
|
||||
{
|
||||
this->processorState = ps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param cs the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
ExprResult* CurrentFunctionCall::evaluate(Node* context, ContextState* cs)
|
||||
/*
|
||||
* Evaluates this Expr
|
||||
*
|
||||
* @return NodeSet containing the context node used for the complete
|
||||
* Expr or Pattern.
|
||||
*/
|
||||
ExprResult* CurrentFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
return new NodeSet(processorState->getCurrentNode());
|
||||
return new NodeSet(mPs->getEvalContext()->getContextNode());
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "XSLTFunctions.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include "Names.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/*
|
||||
* Creates a new DocumentFunctionCall.
|
||||
|
@ -56,19 +57,17 @@ DocumentFunctionCall::DocumentFunctionCall(ProcessorState* aPs,
|
|||
* NOTE: the implementation is incomplete since it does not make use of the
|
||||
* second argument (base URI)
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* DocumentFunctionCall::evaluate(Node* context, ContextState* cs)
|
||||
ExprResult* DocumentFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
NodeSet* nodeSet = new NodeSet();
|
||||
|
||||
// document(object, node-set?)
|
||||
if (requireParams(1, 2, cs)) {
|
||||
if (requireParams(1, 2, aContext)) {
|
||||
ListIterator* iter = params.iterator();
|
||||
Expr* param1 = (Expr*) iter->next();
|
||||
ExprResult* exprResult1 = param1->evaluate(context, cs);
|
||||
ExprResult* exprResult1 = param1->evaluate(aContext);
|
||||
String baseURI;
|
||||
MBool baseURISet = MB_FALSE;
|
||||
|
||||
|
@ -76,11 +75,12 @@ ExprResult* DocumentFunctionCall::evaluate(Node* context, ContextState* cs)
|
|||
// We have 2 arguments, get baseURI from the first node
|
||||
// in the resulting nodeset
|
||||
Expr* param2 = (Expr*) iter->next();
|
||||
ExprResult* exprResult2 = param2->evaluate(context, cs);
|
||||
ExprResult* exprResult2 = param2->evaluate(aContext);
|
||||
if (exprResult2->getResultType() != ExprResult::NODESET) {
|
||||
String err("node-set expected as second argument to document(): ");
|
||||
toString(err);
|
||||
cs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
delete exprResult1;
|
||||
delete exprResult2;
|
||||
return nodeSet;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "XSLTFunctions.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "Names.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/*
|
||||
Implementation of XSLT 1.0 extension function: element-available
|
||||
|
@ -47,9 +48,11 @@
|
|||
|
||||
/**
|
||||
* Creates a new element-available function call
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
ElementAvailableFunctionCall::ElementAvailableFunctionCall() :
|
||||
FunctionCall(ELEMENT_AVAILABLE_FN)
|
||||
ElementAvailableFunctionCall::ElementAvailableFunctionCall(Element* aNode) :
|
||||
mStylesheetNode(aNode), FunctionCall(ELEMENT_AVAILABLE_FN)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -61,24 +64,28 @@ ElementAvailableFunctionCall::ElementAvailableFunctionCall() :
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
ExprResult* ElementAvailableFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
ExprResult* ElementAvailableFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ExprResult* result = NULL;
|
||||
|
||||
if ( requireParams(1,1,cs) ) {
|
||||
if (requireParams(1, 1, aContext)) {
|
||||
ListIterator iter(¶ms);
|
||||
Expr* param = (Expr*) iter.next();
|
||||
ExprResult* exprResult = param->evaluate(context, cs);
|
||||
ExprResult* exprResult = param->evaluate(aContext);
|
||||
if (exprResult &&
|
||||
exprResult->getResultType() == ExprResult::STRING) {
|
||||
String property;
|
||||
exprResult->stringValue(property);
|
||||
if (XMLUtils::isValidQName(property)) {
|
||||
String prefix, propertyNsURI;
|
||||
String prefix;
|
||||
PRInt32 aNSID = kNameSpaceID_None;
|
||||
XMLUtils::getPrefix(property, prefix);
|
||||
if (!prefix.isEmpty()) {
|
||||
cs->getNameSpaceURIFromPrefix(property, propertyNsURI);
|
||||
txAtom* prefixAtom = TX_GET_ATOM(prefix);
|
||||
aNSID = mStylesheetNode->lookupNamespaceID(prefixAtom);
|
||||
TX_IF_RELEASE_ATOM(prefixAtom);
|
||||
}
|
||||
if (propertyNsURI.isEqual(XSLT_NS)) {
|
||||
if (aNSID == kNameSpaceID_XSLT) {
|
||||
String localName;
|
||||
XMLUtils::getLocalPart(property, localName);
|
||||
if ( localName.isEqual(APPLY_IMPORTS) ||
|
||||
|
@ -119,7 +126,7 @@ ExprResult* ElementAvailableFunctionCall::evaluate(Node* context, ContextState*
|
|||
}
|
||||
else {
|
||||
String err("Invalid argument passed to element-available(), expecting String");
|
||||
delete result;
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
result = new StringResult(err);
|
||||
}
|
||||
delete exprResult;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "FunctionLib.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "Names.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
/*
|
||||
Implementation of XSLT 1.0 extension function: function-available
|
||||
|
@ -62,13 +63,14 @@ FunctionAvailableFunctionCall::FunctionAvailableFunctionCall() :
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
ExprResult* FunctionAvailableFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
ExprResult* FunctionAvailableFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ExprResult* result = NULL;
|
||||
|
||||
if ( requireParams(1,1,cs) ) {
|
||||
if (requireParams(1, 1, aContext)) {
|
||||
ListIterator iter(¶ms);
|
||||
Expr* param = (Expr*)iter.next();
|
||||
ExprResult* exprResult = param->evaluate(context, cs);
|
||||
ExprResult* exprResult = param->evaluate(aContext);
|
||||
if (exprResult &&
|
||||
exprResult->getResultType() == ExprResult::STRING) {
|
||||
String property;
|
||||
|
@ -119,7 +121,7 @@ ExprResult* FunctionAvailableFunctionCall::evaluate(Node* context, ContextState*
|
|||
}
|
||||
else {
|
||||
String err("Invalid argument passed to function-available, expecting String");
|
||||
delete result;
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
result = new StringResult(err);
|
||||
}
|
||||
delete exprResult;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "XSLTFunctions.h"
|
||||
#include "Names.h"
|
||||
#include "txIXPathContext.h"
|
||||
#ifdef TX_EXE
|
||||
#include <stdio.h>
|
||||
#else
|
||||
|
@ -55,10 +56,9 @@ GenerateIdFunctionCall::GenerateIdFunctionCall()
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
ExprResult* GenerateIdFunctionCall::evaluate(Node* aContext,
|
||||
ContextState* aCs) {
|
||||
|
||||
if (!requireParams(0, 1, aCs))
|
||||
ExprResult* GenerateIdFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
if (!requireParams(0, 1, aContext))
|
||||
return new StringResult();
|
||||
|
||||
Node* node = 0;
|
||||
|
@ -68,14 +68,14 @@ ExprResult* GenerateIdFunctionCall::evaluate(Node* aContext,
|
|||
txListIterator iter(¶ms);
|
||||
Expr* param = (Expr*)iter.next();
|
||||
|
||||
ExprResult* exprResult = param->evaluate(aContext, aCs);
|
||||
ExprResult* exprResult = param->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return 0;
|
||||
|
||||
if (exprResult->getResultType() != ExprResult::NODESET) {
|
||||
String err("Invalid argument passed to generate-id(), "
|
||||
"expecting NodeSet");
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
delete exprResult;
|
||||
return new StringResult(err);
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ ExprResult* GenerateIdFunctionCall::evaluate(Node* aContext,
|
|||
delete exprResult;
|
||||
}
|
||||
else {
|
||||
node = aContext;
|
||||
node = aContext->getContextNode();
|
||||
}
|
||||
|
||||
// generate id for selected node
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "XSLTFunctions.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "Names.h"
|
||||
#include "txIXPathContext.h"
|
||||
|
||||
const String XSL_VERSION_PROPERTY = "version";
|
||||
const String XSL_VENDOR_PROPERTY = "vendor";
|
||||
|
@ -12,9 +13,11 @@ const String XSL_VENDOR_URL_PROPERTY = "vendor-url";
|
|||
|
||||
/**
|
||||
* Creates a new system-property function call
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
SystemPropertyFunctionCall::SystemPropertyFunctionCall() :
|
||||
FunctionCall(SYSTEM_PROPERTY_FN)
|
||||
SystemPropertyFunctionCall::SystemPropertyFunctionCall(Element* aNode) :
|
||||
mStylesheetNode(aNode), FunctionCall(SYSTEM_PROPERTY_FN)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -26,22 +29,29 @@ SystemPropertyFunctionCall::SystemPropertyFunctionCall() :
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
ExprResult* SystemPropertyFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
ExprResult* SystemPropertyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
ExprResult* result = NULL;
|
||||
|
||||
if ( requireParams(1,1,cs) ) {
|
||||
if (requireParams(1, 1, aContext)) {
|
||||
ListIterator* iter = params.iterator();
|
||||
Expr* param = (Expr*) iter->next();
|
||||
delete iter;
|
||||
ExprResult* exprResult = param->evaluate(context, cs);
|
||||
ExprResult* exprResult = param->evaluate(aContext);
|
||||
if (exprResult->getResultType() == ExprResult::STRING) {
|
||||
String property;
|
||||
exprResult->stringValue(property);
|
||||
if (XMLUtils::isValidQName(property)) {
|
||||
String propertyNsURI, prefix;
|
||||
String prefix;
|
||||
PRInt32 namespaceID = kNameSpaceID_None;
|
||||
XMLUtils::getPrefix(property, prefix);
|
||||
cs->getNameSpaceURIFromPrefix(prefix, propertyNsURI);
|
||||
if (propertyNsURI.isEqual(XSLT_NS)) {
|
||||
if (!prefix.isEmpty()) {
|
||||
txAtom* prefixAtom = TX_GET_ATOM(prefix);
|
||||
namespaceID =
|
||||
mStylesheetNode->lookupNamespaceID(prefixAtom);
|
||||
TX_IF_RELEASE_ATOM(prefixAtom);
|
||||
}
|
||||
if (namespaceID == kNameSpaceID_XSLT) {
|
||||
String localName;
|
||||
XMLUtils::getLocalPart(property, localName);
|
||||
if (localName.isEqual(XSL_VERSION_PROPERTY))
|
||||
|
@ -55,6 +65,7 @@ ExprResult* SystemPropertyFunctionCall::evaluate(Node* context, ContextState* cs
|
|||
}
|
||||
else {
|
||||
String err("Invalid argument passed to system-property(), expecting String");
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
result = new StringResult(err);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,14 +51,9 @@ public:
|
|||
DocumentFunctionCall(ProcessorState* aPs, Node* aDefResolveNode);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param cs the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
* Virtual methods from FunctionCall
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
ProcessorState* mProcessorState;
|
||||
|
@ -80,12 +75,10 @@ public:
|
|||
/*
|
||||
* Evaluates a key() xslt-functioncall. First argument is name of key
|
||||
* to use, second argument is value to look up.
|
||||
* @param aContext the context node for evaluation of this Expr
|
||||
* @param aCs the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*
|
||||
* Virtual function from FunctionCall
|
||||
*/
|
||||
virtual ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
ProcessorState* mProcessorState;
|
||||
|
@ -120,7 +113,7 @@ public:
|
|||
* @param aUse use-expression
|
||||
* @return MB_FALSE if an error occured, MB_TRUE otherwise
|
||||
*/
|
||||
MBool addKey(Pattern* aMatch, Expr* aUse);
|
||||
MBool addKey(txPattern* aMatch, Expr* aUse);
|
||||
|
||||
private:
|
||||
/*
|
||||
|
@ -150,7 +143,7 @@ private:
|
|||
* represents one match/use pair
|
||||
*/
|
||||
struct Key {
|
||||
Pattern* matchPattern;
|
||||
txPattern* matchPattern;
|
||||
Expr* useExpr;
|
||||
};
|
||||
|
||||
|
@ -191,14 +184,9 @@ public:
|
|||
txFormatNumberFunctionCall(ProcessorState* aPs);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param aContext the context node for evaluation of this Expr
|
||||
* @param aCs the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
* Virtual function from FunctionCall
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
static const UNICODE_CHAR FORMAT_QUOTE;
|
||||
|
@ -255,17 +243,12 @@ public:
|
|||
CurrentFunctionCall(ProcessorState* ps);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param cs the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
* Virtual function from FunctionCall
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
ProcessorState* processorState;
|
||||
ProcessorState* mPs;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -288,7 +271,7 @@ public:
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
};
|
||||
|
@ -313,7 +296,7 @@ public:
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
static const char printfFmt[];
|
||||
|
@ -328,8 +311,10 @@ public:
|
|||
|
||||
/**
|
||||
* Creates a new system-property() function call
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
SystemPropertyFunctionCall();
|
||||
SystemPropertyFunctionCall(Element* aNode);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
|
@ -339,9 +324,13 @@ public:
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
/*
|
||||
* resolve namespaceIDs with this node
|
||||
*/
|
||||
Element* mStylesheetNode;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -353,8 +342,10 @@ public:
|
|||
|
||||
/**
|
||||
* Creates a new element-available() function call
|
||||
* aNode is the Element in the stylesheet containing the
|
||||
* Expr and is used for namespaceID resolution
|
||||
**/
|
||||
ElementAvailableFunctionCall();
|
||||
ElementAvailableFunctionCall(Element* aNode);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
|
@ -364,9 +355,13 @@ public:
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
/*
|
||||
* resolve namespaceIDs with this node
|
||||
*/
|
||||
Element* mStylesheetNode;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -389,7 +384,7 @@ public:
|
|||
* @return the result of the evaluation
|
||||
* @see FunctionCall.h
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
ExprResult* evaluate(txIEvalContext* aContext);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "XSLTFunctions.h"
|
||||
#include "primitives.h"
|
||||
#include "Names.h"
|
||||
#include "txIXPathContext.h"
|
||||
#include <math.h>
|
||||
|
||||
#ifndef TX_EXE
|
||||
|
@ -70,10 +71,9 @@ txFormatNumberFunctionCall::txFormatNumberFunctionCall(ProcessorState* aPs) :
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
||||
ContextState* aCs)
|
||||
ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
if (!requireParams(2, 3, aCs))
|
||||
if (!requireParams(2, 3, aContext))
|
||||
return new StringResult();
|
||||
|
||||
// Get number and format
|
||||
|
@ -83,16 +83,16 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
|||
String formatStr;
|
||||
String formatName;
|
||||
|
||||
value = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, formatStr);
|
||||
value = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||
evaluateToString((Expr*)iter.next(), aContext, formatStr);
|
||||
if (iter.hasNext())
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, formatName);
|
||||
evaluateToString((Expr*)iter.next(), aContext, formatName);
|
||||
|
||||
txDecimalFormat* format = mPs->getDecimalFormat(formatName);
|
||||
if (!format) {
|
||||
String err("unknown decimal format for: ");
|
||||
toString(err);
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||
return new StringResult(err);
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,8 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
|||
else {
|
||||
String err(INVALID_PARAM_VALUE);
|
||||
toString(err);
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err,
|
||||
NS_ERROR_XPATH_EVAL_FAILED);
|
||||
return new StringResult(err);
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +172,8 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
|||
else {
|
||||
String err(INVALID_PARAM_VALUE);
|
||||
toString(err);
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err,
|
||||
NS_ERROR_XPATH_EVAL_FAILED);
|
||||
return new StringResult(err);
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +258,8 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
|||
groupSize == 0) {
|
||||
String err(INVALID_PARAM_VALUE);
|
||||
toString(err);
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err,
|
||||
NS_ERROR_XPATH_EVAL_FAILED);
|
||||
return new StringResult(err);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "XSLTFunctions.h"
|
||||
#include "Names.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include "txSingleNodeContext.h"
|
||||
|
||||
/*
|
||||
* txKeyFunctionCall
|
||||
|
@ -44,9 +45,9 @@ txKeyFunctionCall::txKeyFunctionCall(ProcessorState* aPs) :
|
|||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* txKeyFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||
ExprResult* txKeyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||
{
|
||||
if (!aContext || !requireParams(2, 2, aCs))
|
||||
if (!aContext || !requireParams(2, 2, aContext))
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* res = new NodeSet;
|
||||
|
@ -57,26 +58,27 @@ ExprResult* txKeyFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
|||
|
||||
ListIterator iter(¶ms);
|
||||
String keyName;
|
||||
evaluateToString((Expr*)iter.next(), aContext, aCs, keyName);
|
||||
evaluateToString((Expr*)iter.next(), aContext, keyName);
|
||||
Expr* param = (Expr*) iter.next();
|
||||
|
||||
txXSLKey* key = mProcessorState->getKey(keyName);
|
||||
if (!key) {
|
||||
String err("No key with that name in: ");
|
||||
toString(err);
|
||||
aCs->recieveError(err);
|
||||
aContext->receiveError(err, NS_ERROR_INVALID_ARG);
|
||||
return res;
|
||||
}
|
||||
|
||||
ExprResult* exprResult = param->evaluate(aContext, aCs);
|
||||
ExprResult* exprResult = param->evaluate(aContext);
|
||||
if (!exprResult)
|
||||
return res;
|
||||
|
||||
Document* contextDoc;
|
||||
if (aContext->getNodeType() == Node::DOCUMENT_NODE)
|
||||
contextDoc = (Document*)aContext;
|
||||
Node* contextNode = aContext->getContextNode();
|
||||
if (contextNode->getNodeType() == Node::DOCUMENT_NODE)
|
||||
contextDoc = (Document*)contextNode;
|
||||
else
|
||||
contextDoc = aContext->getOwnerDocument();
|
||||
contextDoc = contextNode->getOwnerDocument();
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* nodeSet = (NodeSet*) exprResult;
|
||||
|
@ -155,7 +157,7 @@ const NodeSet* txXSLKey::getNodes(String& aKeyValue, Document* aDoc)
|
|||
* @param aUse use-expression
|
||||
* @return MB_FALSE if an error occured, MB_TRUE otherwise
|
||||
*/
|
||||
MBool txXSLKey::addKey(Pattern* aMatch, Expr* aUse)
|
||||
MBool txXSLKey::addKey(txPattern* aMatch, Expr* aUse)
|
||||
{
|
||||
if (!aMatch || !aUse)
|
||||
return MB_FALSE;
|
||||
|
@ -226,13 +228,12 @@ void txXSLKey::testNode(Node* aNode, NamedMap* aMap)
|
|||
while (iter.hasNext())
|
||||
{
|
||||
Key* key=(Key*)iter.next();
|
||||
if (key->matchPattern->matches(aNode, 0, mProcessorState)) {
|
||||
NodeSet contextNodeSet(aNode);
|
||||
mProcessorState->getNodeSetStack()->push(&contextNodeSet);
|
||||
mProcessorState->pushCurrentNode(aNode);
|
||||
ExprResult* exprResult = key->useExpr->evaluate(aNode, mProcessorState);
|
||||
mProcessorState->popCurrentNode();
|
||||
mProcessorState->getNodeSetStack()->pop();
|
||||
if (key->matchPattern->matches(aNode, mProcessorState)) {
|
||||
txSingleNodeContext evalContext(aNode, mProcessorState);
|
||||
txIEvalContext* prevCon =
|
||||
mProcessorState->setEvalContext(&evalContext);
|
||||
ExprResult* exprResult = key->useExpr->evaluate(&evalContext);
|
||||
mProcessorState->setEvalContext(prevCon);
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* res = (NodeSet*)exprResult;
|
||||
for (int i=0; i<res->size(); i++) {
|
||||
|
|
|
@ -51,6 +51,8 @@ CPP_OBJS= \
|
|||
.\$(OBJDIR)\txRtfHandler.obj \
|
||||
.\$(OBJDIR)\txTextHandler.obj \
|
||||
.\$(OBJDIR)\VariableBinding.obj \
|
||||
.\$(OBJDIR)\txXSLTPatterns.obj \
|
||||
.\$(OBJDIR)\txPatternParser.obj \
|
||||
.\$(OBJDIR)\XSLTProcessor.obj
|
||||
|
||||
!ifdef TX_EXE
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "txPatternParser.h"
|
||||
#include "Names.h"
|
||||
#include "txAtoms.h"
|
||||
|
||||
txPattern* txPatternParser::createPattern(const String& aPattern,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs)
|
||||
{
|
||||
txPattern* pattern = 0;
|
||||
ExprLexer lexer(aPattern);
|
||||
nsresult rv = createUnionPattern(lexer, aContext, aPs, pattern);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report parsing error
|
||||
return 0;
|
||||
}
|
||||
return pattern;
|
||||
}
|
||||
|
||||
nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
txPattern* locPath = 0;
|
||||
|
||||
rv = createLocPathPattern(aLexer, aContext, aPs, locPath);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
short type = aLexer.peek()->type;
|
||||
if (type == Token::END) {
|
||||
aPattern = locPath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (type != Token::UNION_OP) {
|
||||
delete locPath;
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
}
|
||||
|
||||
txUnionPattern* unionPattern = new txUnionPattern();
|
||||
if (!unionPattern) {
|
||||
delete locPath;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = unionPattern->addPattern(locPath);
|
||||
#if 0 // XXX addPattern can't fail yet, it doesn't check for mem
|
||||
if (NS_FAILED(rv)) {
|
||||
delete unionPattern;
|
||||
delete locPath;
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
aLexer.nextToken();
|
||||
do {
|
||||
rv = createLocPathPattern(aLexer, aContext, aPs, locPath);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete unionPattern;
|
||||
return rv;
|
||||
}
|
||||
rv = unionPattern->addPattern(locPath);
|
||||
#if 0 // XXX addPattern can't fail yet, it doesn't check for mem
|
||||
if (NS_FAILED(rv)) {
|
||||
delete unionPattern;
|
||||
delete locPath;
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
type = aLexer.nextToken()->type;
|
||||
} while (type == Token::UNION_OP);
|
||||
|
||||
if (type != Token::END) {
|
||||
delete unionPattern;
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
}
|
||||
|
||||
aPattern = unionPattern;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
MBool isChild = MB_TRUE;
|
||||
MBool isAbsolute = MB_FALSE;
|
||||
txPattern* stepPattern = 0;
|
||||
txLocPathPattern* pathPattern = 0;
|
||||
|
||||
short type = aLexer.peek()->type;
|
||||
switch (type) {
|
||||
case Token::ANCESTOR_OP:
|
||||
isChild = MB_FALSE;
|
||||
isAbsolute = MB_TRUE;
|
||||
aLexer.nextToken();
|
||||
break;
|
||||
case Token::PARENT_OP:
|
||||
aLexer.nextToken();
|
||||
isAbsolute = MB_TRUE;
|
||||
if (aLexer.peek()->type == Token::END ||
|
||||
aLexer.peek()->type == Token::UNION_OP) {
|
||||
aPattern = new txRootPattern(MB_TRUE);
|
||||
return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
break;
|
||||
case Token::FUNCTION_NAME:
|
||||
// id(Literal) or key(Literal, Literal)
|
||||
{
|
||||
String& name = aLexer.nextToken()->value;
|
||||
txAtom* nameAtom = TX_GET_ATOM(name);
|
||||
if (nameAtom == txXPathAtoms::id) {
|
||||
rv = createIdPattern(aLexer, stepPattern);
|
||||
}
|
||||
else if (nameAtom == txXSLTAtoms::key) {
|
||||
rv = createKeyPattern(aLexer, aContext, aPs, stepPattern);
|
||||
}
|
||||
TX_IF_RELEASE_ATOM(nameAtom);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!stepPattern) {
|
||||
rv = createStepPattern(aLexer, aContext, stepPattern);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
type = aLexer.peek()->type;
|
||||
if (!isAbsolute && type != Token::PARENT_OP
|
||||
&& type != Token::ANCESTOR_OP) {
|
||||
aPattern = stepPattern;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
pathPattern = new txLocPathPattern();
|
||||
if (!pathPattern) {
|
||||
delete stepPattern;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (isAbsolute) {
|
||||
txRootPattern* root = new txRootPattern(MB_FALSE);
|
||||
if (!root) {
|
||||
delete stepPattern;
|
||||
delete pathPattern;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = pathPattern->addStep(root, isChild);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete stepPattern;
|
||||
delete pathPattern;
|
||||
delete root;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
rv = pathPattern->addStep(stepPattern, isChild);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete stepPattern;
|
||||
delete pathPattern;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
stepPattern = 0; // stepPattern is part of pathPattern now
|
||||
|
||||
while (type == Token::PARENT_OP || type == Token::ANCESTOR_OP) {
|
||||
isChild = type == Token::PARENT_OP;
|
||||
aLexer.nextToken();
|
||||
rv = createStepPattern(aLexer, aContext, stepPattern);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete pathPattern;
|
||||
return rv;
|
||||
}
|
||||
rv = pathPattern->addStep(stepPattern, isChild);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete stepPattern;
|
||||
delete pathPattern;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
stepPattern = 0; // stepPattern is part of pathPattern now
|
||||
type = aLexer.peek()->type;
|
||||
}
|
||||
aPattern = pathPattern;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult txPatternParser::createIdPattern(ExprLexer& aLexer,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// check for '(' Literal ')'
|
||||
if (aLexer.nextToken()->type != Token::L_PAREN &&
|
||||
aLexer.peek()->type != Token::LITERAL)
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
const String& value = aLexer.nextToken()->value;
|
||||
if (aLexer.nextToken()->type != Token::R_PAREN)
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
aPattern = new txIdPattern(value);
|
||||
return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult txPatternParser::createKeyPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
// check for '(' Literal, Literal ')'
|
||||
if (aLexer.nextToken()->type != Token::L_PAREN &&
|
||||
aLexer.peek()->type != Token::LITERAL)
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
const String& key = aLexer.nextToken()->value;
|
||||
if (aLexer.nextToken()->type != Token::COMMA &&
|
||||
aLexer.peek()->type != Token::LITERAL)
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
const String& value = aLexer.nextToken()->value;
|
||||
if (aLexer.nextToken()->type != Token::R_PAREN)
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
aPattern = new txKeyPattern(aPs, key, value);
|
||||
return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsresult txPatternParser::createStepPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
txPattern*& aPattern)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
MBool isAttr = MB_FALSE;
|
||||
Token* tok = aLexer.peek();
|
||||
if (tok->type == Token::AXIS_IDENTIFIER) {
|
||||
if (ATTRIBUTE_AXIS.isEqual(tok->value)) {
|
||||
isAttr = MB_TRUE;
|
||||
}
|
||||
else if (!CHILD_AXIS.isEqual(tok->value)) {
|
||||
// all done already for CHILD_AXIS, for all others
|
||||
// XXX report unexpected axis error
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
}
|
||||
aLexer.nextToken();
|
||||
}
|
||||
else if (tok->type == Token::AT_SIGN) {
|
||||
aLexer.nextToken();
|
||||
isAttr = MB_TRUE;
|
||||
}
|
||||
tok = aLexer.nextToken();
|
||||
|
||||
txNodeTest* nodeTest = 0;
|
||||
if (tok->type == Token::CNAME) {
|
||||
// resolve QName
|
||||
txAtom *prefix, *lName;
|
||||
PRInt32 nspace;
|
||||
rv = resolveQName(tok->value, prefix, aContext, lName, nspace);
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX error report namespace resolve failed
|
||||
return rv;
|
||||
}
|
||||
if (isAttr) {
|
||||
nodeTest = new txNameTest(prefix, lName, nspace,
|
||||
Node::ATTRIBUTE_NODE);
|
||||
}
|
||||
else {
|
||||
nodeTest = new txNameTest(prefix, lName, nspace,
|
||||
Node::ELEMENT_NODE);
|
||||
}
|
||||
TX_IF_RELEASE_ATOM(prefix);
|
||||
TX_IF_RELEASE_ATOM(lName);
|
||||
if (!nodeTest) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aLexer.pushBack();
|
||||
nodeTest = createNodeTypeTest(aLexer);
|
||||
if (!nodeTest) {
|
||||
// XXX error report NodeTest expected
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
txStepPattern* step = new txStepPattern(nodeTest, isAttr);
|
||||
if (!step) {
|
||||
delete nodeTest;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nodeTest = 0;
|
||||
if (!parsePredicates(step, aLexer, aContext)) {
|
||||
delete step;
|
||||
return NS_ERROR_XPATH_PARSE_FAILED;
|
||||
}
|
||||
|
||||
aPattern = step;
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef TX_PATTERNPARSER_H
|
||||
#define TX_PATTERNPARSER_H
|
||||
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "ExprParser.h"
|
||||
|
||||
class txPatternParser : public ExprParser
|
||||
{
|
||||
public:
|
||||
static txPattern* createPattern(const String& aPattern,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs);
|
||||
protected:
|
||||
static nsresult createUnionPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createLocPathPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createIdPattern(ExprLexer& aLexer,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createKeyPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
ProcessorState* aPs,
|
||||
txPattern*& aPattern);
|
||||
static nsresult createStepPattern(ExprLexer& aLexer,
|
||||
txIParseContext* aContext,
|
||||
txPattern*& aPattern);
|
||||
};
|
||||
|
||||
#endif // TX_PATTERNPARSER_H
|
|
@ -0,0 +1,614 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "txXSLTPatterns.h"
|
||||
#include "txNodeSetContext.h"
|
||||
#include "txForwardContext.h"
|
||||
#include "XSLTFunctions.h"
|
||||
#ifndef TX_EXE
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* txPattern
|
||||
*
|
||||
* Base class of all patterns
|
||||
* Implements only a default getSimplePatterns
|
||||
*/
|
||||
nsresult txPattern::getSimplePatterns(txList& aList)
|
||||
{
|
||||
aList.add(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
txPattern::~txPattern()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* txUnionPattern
|
||||
*
|
||||
* This pattern is returned by the parser for "foo | bar" constructs.
|
||||
* |xsl:template|s should use the simple patterns
|
||||
*/
|
||||
|
||||
/*
|
||||
* Destructor, deletes all LocationPathPatterns
|
||||
*/
|
||||
txUnionPattern::~txUnionPattern()
|
||||
{
|
||||
ListIterator iter(&mLocPathPatterns);
|
||||
while (iter.hasNext()) {
|
||||
delete (txPattern*)iter.next();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult txUnionPattern::addPattern(txPattern* aPattern)
|
||||
{
|
||||
if (!aPattern)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
mLocPathPatterns.add(aPattern);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default priority of this Pattern.
|
||||
* UnionPatterns don't like this.
|
||||
* This should be called on the simple patterns.
|
||||
*/
|
||||
double txUnionPattern::getDefaultPriority()
|
||||
{
|
||||
NS_ASSERTION(0, "Don't call getDefaultPriority on txUnionPattern");
|
||||
return Double::NaN;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether this Pattern matches the given node within
|
||||
* the given context
|
||||
* This should be called on the simple patterns for xsl:template,
|
||||
* but is fine for xsl:key and xsl:number
|
||||
*/
|
||||
MBool txUnionPattern::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
ListIterator iter(&mLocPathPatterns);
|
||||
while (iter.hasNext()) {
|
||||
txPattern* p = (txPattern*)iter.next();
|
||||
if (p->matches(aNode, aContext)) {
|
||||
return MB_TRUE;
|
||||
}
|
||||
}
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
nsresult txUnionPattern::getSimplePatterns(txList& aList)
|
||||
{
|
||||
ListIterator iter(&mLocPathPatterns);
|
||||
while (iter.hasNext()) {
|
||||
aList.add(iter.next());
|
||||
iter.remove();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* The String representation will be appended to any data in the
|
||||
* destination String, to allow cascading calls to other
|
||||
* toString() methods for mLocPathPatterns.
|
||||
*/
|
||||
void txUnionPattern::toString(String& aDest)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
aDest.append("txUnionPattern{");
|
||||
#endif
|
||||
txListIterator iter(&mLocPathPatterns);
|
||||
if (iter.hasNext())
|
||||
((txPattern*)iter.next())->toString(aDest);
|
||||
while (iter.hasNext()) {
|
||||
aDest.append(" | ");
|
||||
((txPattern*)iter.next())->toString(aDest);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
aDest.append("}");
|
||||
#endif
|
||||
} // toString
|
||||
|
||||
|
||||
/*
|
||||
* LocationPathPattern
|
||||
*
|
||||
* a list of step patterns, can start with id or key
|
||||
* (dealt with by the parser)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Destructor, deletes all PathPatterns
|
||||
*/
|
||||
txLocPathPattern::~txLocPathPattern()
|
||||
{
|
||||
ListIterator iter(&mSteps);
|
||||
while (iter.hasNext()) {
|
||||
delete (Step*)iter.next();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult txLocPathPattern::addStep(txPattern* aPattern, MBool isChild)
|
||||
{
|
||||
if (!aPattern)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
Step* step = new Step(aPattern, isChild);
|
||||
if (!step)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mSteps.add(step);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MBool txLocPathPattern::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(aNode && mSteps.getLength(), "Internal error");
|
||||
|
||||
/*
|
||||
* The idea is to split up a path into blocks separated by descendant
|
||||
* operators. For example "foo/bar//baz/bop//ying/yang" is split up into
|
||||
* three blocks. The "ying/yang" block is handled by the first while-loop
|
||||
* and the "foo/bar" and "baz/bop" blocks are handled by the second
|
||||
* while-loop.
|
||||
* A block is considered matched when we find a list of ancestors that
|
||||
* match the block. If there are more than one list of ancestors that
|
||||
* match a block we only need to find the one furthermost down in the
|
||||
* tree.
|
||||
*/
|
||||
|
||||
ListIterator iter(&mSteps);
|
||||
iter.resetToEnd();
|
||||
|
||||
Step* step;
|
||||
step = (Step*)iter.previous();
|
||||
if (!step->pattern->matches(aNode, aContext))
|
||||
return MB_FALSE;
|
||||
Node* node = aNode->getXPathParent();
|
||||
|
||||
while (step->isChild) {
|
||||
step = (Step*)iter.previous();
|
||||
if (!step)
|
||||
return MB_TRUE; // all steps matched
|
||||
if (!node || !step->pattern->matches(node, aContext))
|
||||
return MB_FALSE; // no more ancestors or no match
|
||||
|
||||
node = node->getXPathParent();
|
||||
}
|
||||
|
||||
// We have at least one // path separator
|
||||
Node *blockStart = node;
|
||||
txListIterator blockIter(iter);
|
||||
|
||||
while ((step = (Step*)iter.previous())) {
|
||||
if (!node)
|
||||
return MB_FALSE; // There are more steps in the current block
|
||||
// than ancestors of the tested node
|
||||
|
||||
if (!step->pattern->matches(node, aContext)) {
|
||||
// Didn't match. We restart at beginning of block using a new
|
||||
// start node
|
||||
iter = blockIter;
|
||||
blockStart = blockStart->getXPathParent();
|
||||
node = blockStart;
|
||||
}
|
||||
else {
|
||||
node = node->getXPathParent();
|
||||
if (!step->isChild) {
|
||||
// We've matched an entire block. Set new start iter and start node
|
||||
blockIter = iter;
|
||||
blockStart = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MB_TRUE;
|
||||
} // txLocPathPattern::matches
|
||||
|
||||
double txLocPathPattern::getDefaultPriority()
|
||||
{
|
||||
if (mSteps.getLength() > 1) {
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
return ((Step*)mSteps.get(0))->pattern->getDefaultPriority();
|
||||
}
|
||||
|
||||
void txLocPathPattern::toString(String& aDest)
|
||||
{
|
||||
ListIterator iter(&mSteps);
|
||||
#ifdef DEBUG
|
||||
aDest.append("txLocPathPattern{");
|
||||
#endif
|
||||
Step* step;
|
||||
step = (Step*)iter.next();
|
||||
if (step) {
|
||||
step->pattern->toString(aDest);
|
||||
}
|
||||
while ((step = (Step*)iter.next())) {
|
||||
if (step->isChild)
|
||||
aDest.append("/");
|
||||
else
|
||||
aDest.append("//");
|
||||
step->pattern->toString(aDest);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
aDest.append("}");
|
||||
#endif
|
||||
} // txLocPathPattern::toString
|
||||
|
||||
/*
|
||||
* txRootPattern
|
||||
*
|
||||
* a txPattern matching the document node, or '/'
|
||||
*/
|
||||
|
||||
txRootPattern::~txRootPattern()
|
||||
{
|
||||
}
|
||||
|
||||
MBool txRootPattern::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
return aNode && (aNode->getNodeType() == Node::DOCUMENT_NODE);
|
||||
}
|
||||
|
||||
double txRootPattern::getDefaultPriority()
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
void txRootPattern::toString(String& aDest)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
aDest.append("txRootPattern{");
|
||||
#endif
|
||||
if (mSerialize)
|
||||
aDest.append("/");
|
||||
#ifdef DEBUG
|
||||
aDest.append("}");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* txIdPattern
|
||||
*
|
||||
* txIdPattern matches if the given node has a ID attribute with one
|
||||
* of the space delimited values.
|
||||
* This looks like the id() function, but may only have LITERALs as
|
||||
* argument.
|
||||
*/
|
||||
|
||||
#define TX_IS_WHITE(c) (c == ' ' || c == '\r' || c == '\n'|| c == '\t')
|
||||
|
||||
txIdPattern::txIdPattern(const String aString)
|
||||
{
|
||||
#ifdef TX_EXE
|
||||
mIds = aString;
|
||||
#else
|
||||
const nsString& ids = aString.getConstNSString();
|
||||
nsAString::const_iterator pos, begin, end;
|
||||
ids.BeginReading(begin);
|
||||
ids.EndReading(end);
|
||||
pos = begin;
|
||||
while (pos != end) {
|
||||
while (pos != end && TX_IS_WHITE(*pos))
|
||||
++pos;
|
||||
begin = pos;
|
||||
if (!mIds.IsEmpty())
|
||||
mIds += PRUnichar(' ');
|
||||
while (pos != end && !TX_IS_WHITE(*pos))
|
||||
++pos;
|
||||
mIds += Substring(begin, pos);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
txIdPattern::~txIdPattern()
|
||||
{
|
||||
}
|
||||
|
||||
MBool txIdPattern::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
#ifdef TX_EXE
|
||||
return MB_FALSE; // not implemented
|
||||
#else
|
||||
if (aNode->getNodeType() != Node::ELEMENT_NODE) {
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
// Get a ID attribute, if there is
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode->getNSObj());
|
||||
NS_ASSERTION(content, "a Element without nsIContent");
|
||||
if (!content) {
|
||||
return MB_FALSE;
|
||||
}
|
||||
nsCOMPtr<nsINodeInfo> ni;
|
||||
content->GetNodeInfo(*getter_AddRefs(ni));
|
||||
if (!ni) {
|
||||
return MB_FALSE;
|
||||
}
|
||||
nsCOMPtr<nsIAtom> idAttr;
|
||||
ni->GetIDAttributeAtom(getter_AddRefs(idAttr));
|
||||
if (!idAttr) {
|
||||
return MB_FALSE; // no ID for this element defined, can't match
|
||||
}
|
||||
nsAutoString value;
|
||||
nsresult rv = content->GetAttr(kNameSpaceID_None, idAttr, value);
|
||||
if (rv != NS_CONTENT_ATTR_HAS_VALUE) {
|
||||
return MB_FALSE; // no ID attribute given
|
||||
}
|
||||
nsAString::const_iterator pos, begin, end;
|
||||
mIds.BeginReading(begin);
|
||||
mIds.EndReading(end);
|
||||
pos = begin;
|
||||
const PRUnichar space = PRUnichar(' ');
|
||||
PRBool found = FindCharInReadable(space, pos, end);
|
||||
|
||||
while (found) {
|
||||
if (value.Equals(Substring(begin, pos))) {
|
||||
return MB_TRUE;
|
||||
}
|
||||
++pos; // skip ' '
|
||||
begin = pos;
|
||||
found = FindCharInReadable(PRUnichar(' '), pos, end);
|
||||
}
|
||||
if (value.Equals(Substring(begin, pos))) {
|
||||
return MB_TRUE;
|
||||
}
|
||||
return MB_FALSE;
|
||||
#endif // TX_EXE
|
||||
}
|
||||
|
||||
double txIdPattern::getDefaultPriority()
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
void txIdPattern::toString(String& aDest)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
aDest.append("txIdPattern{");
|
||||
#endif
|
||||
aDest.append("id('");
|
||||
#ifdef TX_EXE
|
||||
aDest.append(mIds);
|
||||
#else
|
||||
aDest.append(mIds.get());
|
||||
#endif
|
||||
aDest.append("')");
|
||||
#ifdef DEBUG
|
||||
aDest.append("}");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* txKeyPattern
|
||||
*
|
||||
* txKeyPattern matches if the given node is in the evalation of
|
||||
* the key() function
|
||||
* This resembles the key() function, but may only have LITERALs as
|
||||
* argument.
|
||||
*/
|
||||
|
||||
txKeyPattern::~txKeyPattern()
|
||||
{
|
||||
}
|
||||
|
||||
MBool txKeyPattern::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
Document* contextDoc;
|
||||
if (aNode->getNodeType() == Node::DOCUMENT_NODE)
|
||||
contextDoc = (Document*)aNode;
|
||||
else
|
||||
contextDoc = aNode->getOwnerDocument();
|
||||
txXSLKey* key = mProcessorState->getKey(mName);
|
||||
const NodeSet* nodes = key->getNodes(mValue, contextDoc);
|
||||
if (!nodes || nodes->isEmpty())
|
||||
return MB_FALSE;
|
||||
MBool isTrue = nodes->contains(aNode);
|
||||
return isTrue;
|
||||
}
|
||||
|
||||
double txKeyPattern::getDefaultPriority()
|
||||
{
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
void txKeyPattern::toString(String& aDest)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
aDest.append("txKeyPattern{");
|
||||
#endif
|
||||
aDest.append("key('");
|
||||
aDest.append(mName);
|
||||
aDest.append(", ");
|
||||
aDest.append(mValue);
|
||||
aDest.append("')");
|
||||
#ifdef DEBUG
|
||||
aDest.append("}");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* txStepPattern
|
||||
*
|
||||
* a txPattern to hold the NodeTest and the Predicates of a StepPattern
|
||||
*/
|
||||
|
||||
txStepPattern::~txStepPattern()
|
||||
{
|
||||
delete mNodeTest;
|
||||
}
|
||||
|
||||
MBool txStepPattern::matches(Node* aNode, txIMatchContext* aContext)
|
||||
{
|
||||
NS_ASSERTION(mNodeTest && aNode, "Internal error");
|
||||
if (!aNode)
|
||||
return MB_FALSE;
|
||||
|
||||
if (!mNodeTest->matches(aNode, aContext))
|
||||
return MB_FALSE;
|
||||
|
||||
if (!mIsAttr && !aNode->getParentNode())
|
||||
return MB_FALSE;
|
||||
if (isEmpty()) {
|
||||
return MB_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluate Predicates
|
||||
*
|
||||
* Copy all siblings/attributes matching mNodeTest to nodes
|
||||
* Up to the last Predicate do
|
||||
* Foreach node in nodes
|
||||
* evaluate Predicate with node as context node
|
||||
* if the result is a number, check the context position,
|
||||
* otherwise convert to bool
|
||||
* if result is true, copy node to newNodes
|
||||
* if aNode is not member of newNodes, return MB_FALSE
|
||||
* nodes = newNodes
|
||||
*
|
||||
* For the last Predicate, evaluate Predicate with aNode as
|
||||
* context node, if the result is a number, check the position,
|
||||
* otherwise return the result converted to boolean
|
||||
*/
|
||||
|
||||
// Create the context node set for evaluating the predicates
|
||||
NodeSet nodes;
|
||||
Node* parent = aNode->getXPathParent();
|
||||
if (mIsAttr) {
|
||||
NamedNodeMap* atts = parent->getAttributes();
|
||||
if (atts) {
|
||||
PRUint32 i;
|
||||
for (i = 0; i < atts->getLength(); i++) {
|
||||
Node* attr = atts->item(i);
|
||||
if (mNodeTest->matches(attr, aContext))
|
||||
nodes.append(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Node* tmpNode = parent->getFirstChild();
|
||||
while (tmpNode) {
|
||||
if (mNodeTest->matches(tmpNode, aContext))
|
||||
nodes.append(tmpNode);
|
||||
tmpNode = tmpNode->getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
txListIterator iter(&predicates);
|
||||
Expr* predicate = (Expr*)iter.next();
|
||||
NodeSet newNodes;
|
||||
|
||||
while (iter.hasNext()) {
|
||||
newNodes.clear();
|
||||
MBool contextIsInPredicate = MB_FALSE;
|
||||
txNodeSetContext predContext(&nodes, aContext);
|
||||
while (predContext.hasNext()) {
|
||||
predContext.next();
|
||||
ExprResult* exprResult = predicate->evaluate(&predContext);
|
||||
if (!exprResult)
|
||||
break;
|
||||
switch(exprResult->getResultType()) {
|
||||
case ExprResult::NUMBER :
|
||||
// handle default, [position() == numberValue()]
|
||||
if ((double)predContext.position() ==
|
||||
exprResult->numberValue()) {
|
||||
Node* tmp = predContext.getContextNode();
|
||||
if (tmp == aNode)
|
||||
contextIsInPredicate = MB_TRUE;
|
||||
newNodes.append(tmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (exprResult->booleanValue()) {
|
||||
Node* tmp = predContext.getContextNode();
|
||||
if (tmp == aNode)
|
||||
contextIsInPredicate = MB_TRUE;
|
||||
newNodes.append(tmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
delete exprResult;
|
||||
}
|
||||
// Move new NodeSet to the current one
|
||||
nodes.clear();
|
||||
nodes.append(&newNodes);
|
||||
if (!contextIsInPredicate) {
|
||||
return MB_FALSE;
|
||||
}
|
||||
predicate = (Expr*)iter.next();
|
||||
}
|
||||
txForwardContext evalContext(aContext, aNode, &nodes);
|
||||
ExprResult* exprResult = predicate->evaluate(&evalContext);
|
||||
if (!exprResult)
|
||||
return MB_FALSE;
|
||||
if (exprResult->getResultType() == ExprResult::NUMBER)
|
||||
// handle default, [position() == numberValue()]
|
||||
return ((double)evalContext.position() == exprResult->numberValue());
|
||||
|
||||
return exprResult->booleanValue();
|
||||
} // matches
|
||||
|
||||
double txStepPattern::getDefaultPriority()
|
||||
{
|
||||
if (isEmpty())
|
||||
return mNodeTest->getDefaultPriority();
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
void txStepPattern::toString(String& aDest)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
aDest.append("txStepPattern{");
|
||||
#endif
|
||||
if (mIsAttr)
|
||||
aDest.append("@");
|
||||
if (mNodeTest)
|
||||
mNodeTest->toString(aDest);
|
||||
|
||||
PredicateList::toString(aDest);
|
||||
#ifdef DEBUG
|
||||
aDest.append("}");
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT Processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Axel Hecht.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef TX_XSLT_PATTERNS_H
|
||||
#define TX_XSLT_PATTERNS_H
|
||||
|
||||
#include "Expr.h"
|
||||
class ProcessorState;
|
||||
|
||||
class txPattern : public TxObject
|
||||
{
|
||||
public:
|
||||
virtual ~txPattern();
|
||||
|
||||
/*
|
||||
* Determines whether this Pattern matches the given node.
|
||||
*/
|
||||
virtual MBool matches(Node* aNode, txIMatchContext* aContext) = 0;
|
||||
|
||||
/*
|
||||
* Returns the default priority of this Pattern.
|
||||
*
|
||||
* Simple Patterns return the values as specified in XPath 5.5.
|
||||
* Returns -Inf for union patterns, as it shouldn't be called on them.
|
||||
*/
|
||||
virtual double getDefaultPriority() = 0;
|
||||
|
||||
/*
|
||||
* Returns the String representation of this Pattern.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Patterns.
|
||||
* @return the String representation of this Pattern.
|
||||
*/
|
||||
virtual void toString(String& aDest) = 0;
|
||||
|
||||
/*
|
||||
* Adds the simple Patterns to the List.
|
||||
* For union patterns, add all sub patterns,
|
||||
* all other (simple) patterns just add themselves.
|
||||
* This cuts the ownership of the union pattern and it's
|
||||
* simple patterns, leaving union patterns empty after a call
|
||||
* to this function.
|
||||
*/
|
||||
virtual nsresult getSimplePatterns(txList &aList);
|
||||
};
|
||||
|
||||
#define TX_DECL_PATTERN \
|
||||
MBool matches(Node* aNode, txIMatchContext* aContext); \
|
||||
double getDefaultPriority(); \
|
||||
void toString(String& aDest)
|
||||
#define TX_DECL_PATTERN2 \
|
||||
TX_DECL_PATTERN; \
|
||||
nsresult getSimplePatterns(txList &aList)
|
||||
|
||||
|
||||
class txUnionPattern : public txPattern
|
||||
{
|
||||
public:
|
||||
txUnionPattern()
|
||||
{
|
||||
}
|
||||
|
||||
~txUnionPattern();
|
||||
|
||||
nsresult addPattern(txPattern* aPattern);
|
||||
|
||||
TX_DECL_PATTERN2;
|
||||
|
||||
private:
|
||||
txList mLocPathPatterns;
|
||||
};
|
||||
|
||||
class txLocPathPattern : public txPattern
|
||||
{
|
||||
public:
|
||||
txLocPathPattern()
|
||||
{
|
||||
}
|
||||
|
||||
~txLocPathPattern();
|
||||
|
||||
nsresult addStep(txPattern* aPattern, MBool isChild);
|
||||
|
||||
TX_DECL_PATTERN;
|
||||
|
||||
private:
|
||||
class Step {
|
||||
public:
|
||||
Step(txPattern* aPattern, MBool aIsChild)
|
||||
: pattern(aPattern), isChild(aIsChild)
|
||||
{
|
||||
}
|
||||
|
||||
~Step()
|
||||
{
|
||||
delete pattern;
|
||||
}
|
||||
|
||||
txPattern* pattern;
|
||||
MBool isChild;
|
||||
};
|
||||
|
||||
txList mSteps;
|
||||
};
|
||||
|
||||
class txRootPattern : public txPattern
|
||||
{
|
||||
public:
|
||||
txRootPattern(MBool aSerialize) : mSerialize(aSerialize)
|
||||
{
|
||||
}
|
||||
|
||||
~txRootPattern();
|
||||
|
||||
TX_DECL_PATTERN;
|
||||
private:
|
||||
// Don't serialize txRootPattern if it's used in a txLocPathPattern
|
||||
MBool mSerialize;
|
||||
};
|
||||
|
||||
class txIdPattern : public txPattern
|
||||
{
|
||||
public:
|
||||
txIdPattern(const String aString);
|
||||
|
||||
~txIdPattern();
|
||||
|
||||
TX_DECL_PATTERN;
|
||||
|
||||
private:
|
||||
#ifdef TX_EXE
|
||||
String mIds;
|
||||
#else
|
||||
nsAutoString mIds;
|
||||
#endif
|
||||
};
|
||||
|
||||
class txKeyPattern : public txPattern
|
||||
{
|
||||
public:
|
||||
txKeyPattern(ProcessorState* aPs, const String& aName,
|
||||
const String& aValue)
|
||||
: mProcessorState(aPs), mName(aName), mValue(aValue)
|
||||
{
|
||||
}
|
||||
|
||||
~txKeyPattern();
|
||||
|
||||
TX_DECL_PATTERN;
|
||||
|
||||
private:
|
||||
ProcessorState* mProcessorState;
|
||||
String mName, mValue;
|
||||
};
|
||||
|
||||
class txStepPattern : public PredicateList, public txPattern
|
||||
{
|
||||
public:
|
||||
txStepPattern(txNodeTest* aNodeTest, MBool isAttr)
|
||||
:mNodeTest(aNodeTest), mIsAttr(isAttr)
|
||||
{
|
||||
}
|
||||
|
||||
~txStepPattern();
|
||||
|
||||
TX_DECL_PATTERN;
|
||||
|
||||
private:
|
||||
txNodeTest* mNodeTest;
|
||||
MBool mIsAttr;
|
||||
};
|
||||
|
||||
#endif // TX_XSLT_PATTERNS_H
|
|
@ -43,6 +43,7 @@
|
|||
#include "ProcessorState.h"
|
||||
#include "txXPathResultComparator.h"
|
||||
#include "txAtoms.h"
|
||||
#include "txForwardContext.h"
|
||||
|
||||
/*
|
||||
* Sorts Nodes as specified by the W3C XSLT 1.0 Recommendation
|
||||
|
@ -84,9 +85,8 @@ MBool txNodeSorter::addSortElement(Element* aSortElement,
|
|||
key->mExpr = mPs->getExpr(aSortElement, ProcessorState::SelectAttr);
|
||||
else {
|
||||
if (!mDefaultExpr) {
|
||||
String expr(".");
|
||||
ExprParser parser;
|
||||
mDefaultExpr = parser.createExpr(expr);
|
||||
txNodeTest* test = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
mDefaultExpr = new LocationStep(test, LocationStep::SELF_AXIS);
|
||||
}
|
||||
key->mExpr = mDefaultExpr;
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ MBool txNodeSorter::sortNodeSet(NodeSet* aNodes)
|
|||
}
|
||||
iter.reset();
|
||||
SortableNode* compNode = (SortableNode*)iter.next();
|
||||
while (compNode && (compareNodes(currNode, compNode) > 0)) {
|
||||
while (compNode && (compareNodes(currNode, compNode, aNodes) > 0)) {
|
||||
compNode = (SortableNode*)iter.next();
|
||||
}
|
||||
// ... and insert in sorted list
|
||||
|
@ -211,7 +211,8 @@ MBool txNodeSorter::sortNodeSet(NodeSet* aNodes)
|
|||
}
|
||||
|
||||
int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||
SortableNode* aSNode2)
|
||||
SortableNode* aSNode2,
|
||||
NodeSet* aNodes)
|
||||
{
|
||||
txListIterator iter(&mSortKeys);
|
||||
int i;
|
||||
|
@ -221,9 +222,10 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
|||
SortKey* key = (SortKey*)iter.next();
|
||||
// Lazy create sort values
|
||||
if (!aSNode1->mSortValues[i]) {
|
||||
mPs->pushCurrentNode(aSNode1->mNode);
|
||||
ExprResult* res = key->mExpr->evaluate(aSNode1->mNode, mPs);
|
||||
mPs->popCurrentNode();
|
||||
txForwardContext evalContext(mPs, aSNode1->mNode, aNodes);
|
||||
txIEvalContext* priorEC = mPs->setEvalContext(&evalContext);
|
||||
ExprResult* res = key->mExpr->evaluate(&evalContext);
|
||||
mPs->setEvalContext(priorEC);
|
||||
if (!res) {
|
||||
// XXX ErrorReport
|
||||
return -1;
|
||||
|
@ -236,9 +238,10 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
|||
delete res;
|
||||
}
|
||||
if (!aSNode2->mSortValues[i]) {
|
||||
mPs->pushCurrentNode(aSNode2->mNode);
|
||||
ExprResult* res = key->mExpr->evaluate(aSNode2->mNode, mPs);
|
||||
mPs->popCurrentNode();
|
||||
txForwardContext evalContext(mPs, aSNode2->mNode, aNodes);
|
||||
txIEvalContext* priorEC = mPs->setEvalContext(&evalContext);
|
||||
ExprResult* res = key->mExpr->evaluate(&evalContext);
|
||||
mPs->setEvalContext(priorEC);
|
||||
if (!res) {
|
||||
// XXX ErrorReport
|
||||
return -1;
|
||||
|
@ -272,7 +275,7 @@ MBool txNodeSorter::getAttrAsAVT(Element* aSortElement,
|
|||
if (!aSortElement->getAttr(aAttrName, kNameSpaceID_None, attValue))
|
||||
return MB_FALSE;
|
||||
|
||||
mPs->processAttrValueTemplate(attValue, aContext, aResult);
|
||||
mPs->processAttrValueTemplate(attValue, aSortElement, aResult);
|
||||
return MB_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,8 @@ private:
|
|||
};
|
||||
|
||||
int compareNodes(SortableNode* sNode1,
|
||||
SortableNode* sNode2);
|
||||
SortableNode* sNode2,
|
||||
NodeSet* aNodes);
|
||||
|
||||
MBool getAttrAsAVT(Element* aSortElement,
|
||||
txAtom* aAttrName,
|
||||
|
|
Загрузка…
Ссылка в новой задаче