зеркало из https://github.com/mozilla/pjs.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:
Родитель
34592d5d5b
Коммит
737630761b
|
@ -68,4 +68,9 @@ typedef PRUint32 nsresult;
|
||||||
|
|
||||||
#endif // TX_EXE
|
#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
|
#endif // __TX_ERROR
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "baseutils.h"
|
#include "baseutils.h"
|
||||||
#include "TxString.h"
|
#include "TxString.h"
|
||||||
|
#include "txError.h"
|
||||||
#include <iostream.h>
|
#include <iostream.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,23 +38,26 @@ class ErrorObserver {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum ErrorLevel {FATAL = 0, NORMAL, WARNING};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Destructor for ErrorObserver
|
* Default Destructor for ErrorObserver
|
||||||
**/
|
**/
|
||||||
virtual ~ErrorObserver() {};
|
virtual ~ErrorObserver() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies this Error observer of a new error, with default
|
* Notifies this Error observer of a new error aRes
|
||||||
* level of NORMAL
|
|
||||||
**/
|
**/
|
||||||
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
|
}; //-- ErrorObserver
|
||||||
|
|
||||||
|
@ -79,15 +83,9 @@ public:
|
||||||
virtual ~SimpleErrorObserver() {};
|
virtual ~SimpleErrorObserver() {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies this Error observer of a new error, with default
|
* Notifies this Error observer of a new error aRes
|
||||||
* level of NORMAL
|
|
||||||
**/
|
**/
|
||||||
virtual void recieveError(String& errorMessage);
|
void receiveError(const String& errorMessage, nsresult aRes);
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies this Error observer of a new error using the given error level
|
|
||||||
**/
|
|
||||||
virtual void recieveError(String& errorMessage, ErrorLevel level);
|
|
||||||
|
|
||||||
virtual void supressWarnings(MBool supress);
|
virtual void supressWarnings(MBool supress);
|
||||||
|
|
||||||
|
|
|
@ -45,39 +45,21 @@ SimpleErrorObserver::SimpleErrorObserver(ostream& errStream) {
|
||||||
hideWarnings = MB_FALSE;
|
hideWarnings = MB_FALSE;
|
||||||
} //-- SimpleErrorObserver
|
} //-- 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
|
* 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
|
#ifdef TX_EXE
|
||||||
switch ( level ) {
|
if (NS_FAILED(aRes)) {
|
||||||
case ErrorObserver::FATAL :
|
*errStream << "error: ";
|
||||||
*errStream << "fatal error: ";
|
|
||||||
break;
|
|
||||||
case ErrorObserver::WARNING :
|
|
||||||
if ( hideWarnings ) return;
|
|
||||||
*errStream << "warning: ";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*errStream << "error: ";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*errStream << errorMessage << endl;
|
*errStream << errorMessage << endl;
|
||||||
errStream->flush();
|
errStream->flush();
|
||||||
#endif
|
#endif
|
||||||
} //-- recieveError
|
}
|
||||||
|
|
||||||
void SimpleErrorObserver::supressWarnings(MBool supress) {
|
void SimpleErrorObserver::supressWarnings(MBool supress) {
|
||||||
this->hideWarnings = supress;
|
this->hideWarnings = supress;
|
||||||
|
|
|
@ -61,19 +61,13 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
|
||||||
../xml/dom/standalone/ProcessingInstruction.$(OBJ_SUFFIX) \
|
../xml/dom/standalone/ProcessingInstruction.$(OBJ_SUFFIX) \
|
||||||
../xml/dom/standalone/Text.$(OBJ_SUFFIX) \
|
../xml/dom/standalone/Text.$(OBJ_SUFFIX) \
|
||||||
../xpath/AdditiveExpr.$(OBJ_SUFFIX) \
|
../xpath/AdditiveExpr.$(OBJ_SUFFIX) \
|
||||||
../xpath/AttributeExpr.$(OBJ_SUFFIX) \
|
|
||||||
../xpath/AttributeValueTemplate.$(OBJ_SUFFIX) \
|
../xpath/AttributeValueTemplate.$(OBJ_SUFFIX) \
|
||||||
../xpath/BasicNodeExpr.$(OBJ_SUFFIX) \
|
|
||||||
../xpath/BooleanExpr.$(OBJ_SUFFIX) \
|
../xpath/BooleanExpr.$(OBJ_SUFFIX) \
|
||||||
../xpath/BooleanFunctionCall.$(OBJ_SUFFIX) \
|
../xpath/BooleanFunctionCall.$(OBJ_SUFFIX) \
|
||||||
../xpath/BooleanResult.$(OBJ_SUFFIX) \
|
../xpath/BooleanResult.$(OBJ_SUFFIX) \
|
||||||
../xpath/ElementExpr.$(OBJ_SUFFIX) \
|
|
||||||
../xpath/ErrorFunctionCall.$(OBJ_SUFFIX) \
|
|
||||||
../xpath/Expr.$(OBJ_SUFFIX) \
|
|
||||||
../xpath/ExprLexer.$(OBJ_SUFFIX) \
|
../xpath/ExprLexer.$(OBJ_SUFFIX) \
|
||||||
../xpath/ExprLexerChars.$(OBJ_SUFFIX) \
|
../xpath/ExprLexerChars.$(OBJ_SUFFIX) \
|
||||||
../xpath/ExprParser.$(OBJ_SUFFIX) \
|
../xpath/ExprParser.$(OBJ_SUFFIX) \
|
||||||
../xpath/ExtensionFunctionCall.$(OBJ_SUFFIX) \
|
|
||||||
../xpath/FilterExpr.$(OBJ_SUFFIX) \
|
../xpath/FilterExpr.$(OBJ_SUFFIX) \
|
||||||
../xpath/FunctionCall.$(OBJ_SUFFIX) \
|
../xpath/FunctionCall.$(OBJ_SUFFIX) \
|
||||||
../xpath/LocationStep.$(OBJ_SUFFIX) \
|
../xpath/LocationStep.$(OBJ_SUFFIX) \
|
||||||
|
@ -90,7 +84,10 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
|
||||||
../xpath/StringExpr.$(OBJ_SUFFIX) \
|
../xpath/StringExpr.$(OBJ_SUFFIX) \
|
||||||
../xpath/StringFunctionCall.$(OBJ_SUFFIX) \
|
../xpath/StringFunctionCall.$(OBJ_SUFFIX) \
|
||||||
../xpath/StringResult.$(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/UnionExpr.$(OBJ_SUFFIX) \
|
||||||
../xpath/UnaryExpr.$(OBJ_SUFFIX) \
|
../xpath/UnaryExpr.$(OBJ_SUFFIX) \
|
||||||
../xpath/VariableRefExpr.$(OBJ_SUFFIX) \
|
../xpath/VariableRefExpr.$(OBJ_SUFFIX) \
|
||||||
|
@ -111,6 +108,8 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
|
||||||
../xslt/txTextHandler.$(OBJ_SUFFIX) \
|
../xslt/txTextHandler.$(OBJ_SUFFIX) \
|
||||||
../xslt/txTextOutput.$(OBJ_SUFFIX) \
|
../xslt/txTextOutput.$(OBJ_SUFFIX) \
|
||||||
../xslt/txXMLOutput.$(OBJ_SUFFIX) \
|
../xslt/txXMLOutput.$(OBJ_SUFFIX) \
|
||||||
|
../xslt/txXSLTPatterns.$(OBJ_SUFFIX) \
|
||||||
|
../xslt/txPatternParser.$(OBJ_SUFFIX) \
|
||||||
../xslt/VariableBinding.$(OBJ_SUFFIX) \
|
../xslt/VariableBinding.$(OBJ_SUFFIX) \
|
||||||
../xslt/XSLTProcessor.$(OBJ_SUFFIX) \
|
../xslt/XSLTProcessor.$(OBJ_SUFFIX) \
|
||||||
../xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
|
../xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
|
||||||
|
|
|
@ -40,19 +40,13 @@ REQUIRES = string \
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CPPSRCS = AdditiveExpr.cpp \
|
CPPSRCS = AdditiveExpr.cpp \
|
||||||
AttributeExpr.cpp \
|
|
||||||
AttributeValueTemplate.cpp \
|
AttributeValueTemplate.cpp \
|
||||||
BasicNodeExpr.cpp \
|
|
||||||
BooleanExpr.cpp \
|
BooleanExpr.cpp \
|
||||||
BooleanFunctionCall.cpp \
|
BooleanFunctionCall.cpp \
|
||||||
BooleanResult.cpp \
|
BooleanResult.cpp \
|
||||||
ElementExpr.cpp \
|
|
||||||
ErrorFunctionCall.cpp \
|
|
||||||
Expr.cpp \
|
|
||||||
ExprLexer.cpp \
|
ExprLexer.cpp \
|
||||||
ExprLexerChars.cpp \
|
ExprLexerChars.cpp \
|
||||||
ExprParser.cpp \
|
ExprParser.cpp \
|
||||||
ExtensionFunctionCall.cpp \
|
|
||||||
FilterExpr.cpp \
|
FilterExpr.cpp \
|
||||||
FunctionCall.cpp \
|
FunctionCall.cpp \
|
||||||
LocationStep.cpp \
|
LocationStep.cpp \
|
||||||
|
@ -69,7 +63,10 @@ CPPSRCS = AdditiveExpr.cpp \
|
||||||
StringExpr.cpp \
|
StringExpr.cpp \
|
||||||
StringFunctionCall.cpp \
|
StringFunctionCall.cpp \
|
||||||
StringResult.cpp \
|
StringResult.cpp \
|
||||||
TextExpr.cpp \
|
txNameTest.cpp \
|
||||||
|
txNodeTypeTest.cpp \
|
||||||
|
txForwardContext.cpp \
|
||||||
|
txNodeSetContext.cpp \
|
||||||
UnionExpr.cpp \
|
UnionExpr.cpp \
|
||||||
UnaryExpr.cpp \
|
UnaryExpr.cpp \
|
||||||
VariableRefExpr.cpp \
|
VariableRefExpr.cpp \
|
||||||
|
@ -87,6 +84,7 @@ include $(topsrcdir)/config/rules.mk
|
||||||
INCLUDES += -I$(srcdir) -I$(srcdir)/../base \
|
INCLUDES += -I$(srcdir) -I$(srcdir)/../base \
|
||||||
-I$(srcdir)/../xml -I$(srcdir)/../xml/dom \
|
-I$(srcdir)/../xml -I$(srcdir)/../xml/dom \
|
||||||
-I$(srcdir)/../xslt -I$(srcdir)/../xslt/util \
|
-I$(srcdir)/../xslt -I$(srcdir)/../xslt/util \
|
||||||
-I$(srcdir)/../xslt/functions
|
-I$(srcdir)/../xslt/functions \
|
||||||
|
-I$(srcdir)
|
||||||
|
|
||||||
libs:: $(OBJS)
|
libs:: $(OBJS)
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include "nsXPathNSResolver.h"
|
#include "nsXPathNSResolver.h"
|
||||||
#include "nsXPathResult.h"
|
#include "nsXPathResult.h"
|
||||||
#include "ProcessorState.h"
|
#include "ProcessorState.h"
|
||||||
|
#include "nsContentCID.h"
|
||||||
|
#include "ExprParser.h"
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsXPathEvaluator)
|
NS_IMPL_ADDREF(nsXPathEvaluator)
|
||||||
NS_IMPL_RELEASE(nsXPathEvaluator)
|
NS_IMPL_RELEASE(nsXPathEvaluator)
|
||||||
|
@ -69,8 +71,8 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression,
|
||||||
nsIDOMXPathExpression **aResult)
|
nsIDOMXPathExpression **aResult)
|
||||||
{
|
{
|
||||||
String expressionString(PromiseFlatString(aExpression).get());
|
String expressionString(PromiseFlatString(aExpression).get());
|
||||||
// XXX (pvdb) TODO Set the right resolver on the ExprParser
|
ParseContextImpl pContext(aResolver);
|
||||||
Expr* expression = mParser.createExpr(expressionString);
|
Expr* expression = ExprParser::createExpr(expressionString, &pContext);
|
||||||
if (!expression)
|
if (!expression)
|
||||||
return NS_ERROR_DOM_INVALID_EXPRESSION_ERR;
|
return NS_ERROR_DOM_INVALID_EXPRESSION_ERR;
|
||||||
|
|
||||||
|
@ -114,3 +116,58 @@ nsXPathEvaluator::Evaluate(const nsAString & aExpression,
|
||||||
|
|
||||||
return expression->Evaluate(aContextNode, aType, aInResult, aResult);
|
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__
|
#define nsXPathEvaluator_h__
|
||||||
|
|
||||||
#include "nsIDOMXPathEvaluator.h"
|
#include "nsIDOMXPathEvaluator.h"
|
||||||
#include "ExprParser.h"
|
#include "txIXPathContext.h"
|
||||||
|
#include "nsINameSpaceManager.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class for evaluating an XPath expression string
|
* A class for evaluating an XPath expression string
|
||||||
|
@ -59,7 +60,34 @@ public:
|
||||||
NS_DECL_NSIDOMXPATHEVALUATOR
|
NS_DECL_NSIDOMXPATHEVALUATOR
|
||||||
|
|
||||||
private:
|
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 */
|
/* d0a75e02-b5e7-11d5-a7f2-df109fb8a1fc */
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include "nsIDOMClassInfo.h"
|
#include "nsIDOMClassInfo.h"
|
||||||
#include "nsIDOMXPathNamespace.h"
|
#include "nsIDOMXPathNamespace.h"
|
||||||
#include "nsXPathResult.h"
|
#include "nsXPathResult.h"
|
||||||
#include "ProcessorState.h"
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF(nsXPathExpression)
|
NS_IMPL_ADDREF(nsXPathExpression)
|
||||||
NS_IMPL_RELEASE(nsXPathExpression)
|
NS_IMPL_RELEASE(nsXPathExpression)
|
||||||
|
@ -112,8 +111,8 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
|
||||||
Document document(ownerDOMDocument);
|
Document document(ownerDOMDocument);
|
||||||
Node* node = document.createWrapper(aContextNode);
|
Node* node = document.createWrapper(aContextNode);
|
||||||
|
|
||||||
ProcessorState processorState;
|
EvalContextImpl eContext(node);
|
||||||
ExprResult* exprResult = mExpression->evaluate(node, &processorState);
|
ExprResult* exprResult = mExpression->evaluate(&eContext);
|
||||||
NS_ENSURE_TRUE(exprResult, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(exprResult, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
PRUint16 resultType = aType;
|
PRUint16 resultType = aType;
|
||||||
|
@ -152,3 +151,43 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
|
||||||
|
|
||||||
return CallQueryInterface(xpathResult, aResult);
|
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__
|
#define nsXPathExpression_h__
|
||||||
|
|
||||||
#include "nsIDOMXPathExpression.h"
|
#include "nsIDOMXPathExpression.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
class Expr;
|
class Expr;
|
||||||
|
|
||||||
|
@ -61,6 +62,29 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expr* mExpression;
|
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
|
#endif
|
||||||
|
|
|
@ -53,21 +53,20 @@ AdditiveExpr::~AdditiveExpr() {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* AdditiveExpr::evaluate(Node* context, ContextState* cs) {
|
ExprResult* AdditiveExpr::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
|
|
||||||
double rightDbl = Double::NaN;
|
double rightDbl = Double::NaN;
|
||||||
ExprResult* exprRes = 0;
|
ExprResult* exprRes = 0;
|
||||||
|
|
||||||
if ( rightExpr ) {
|
if ( rightExpr ) {
|
||||||
exprRes = rightExpr->evaluate(context, cs);
|
exprRes = rightExpr->evaluate(aContext);
|
||||||
if ( exprRes ) rightDbl = exprRes->numberValue();
|
if ( exprRes ) rightDbl = exprRes->numberValue();
|
||||||
delete exprRes;
|
delete exprRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
double leftDbl = Double::NaN;
|
double leftDbl = Double::NaN;
|
||||||
if ( leftExpr ) {
|
if ( leftExpr ) {
|
||||||
exprRes = leftExpr->evaluate(context, cs);
|
exprRes = leftExpr->evaluate(aContext);
|
||||||
if ( exprRes ) leftDbl = exprRes->numberValue();
|
if ( exprRes ) leftDbl = exprRes->numberValue();
|
||||||
delete exprRes;
|
delete exprRes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,12 +62,13 @@ void AttributeValueTemplate::addExpr(Expr* expr) {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* AttributeValueTemplate::evaluate(Node* context, ContextState* cs) {
|
ExprResult* AttributeValueTemplate::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
ListIterator* iter = expressions.iterator();
|
ListIterator* iter = expressions.iterator();
|
||||||
String result;
|
String result;
|
||||||
while ( iter->hasNext() ) {
|
while ( iter->hasNext() ) {
|
||||||
Expr* expr = (Expr*)iter->next();
|
Expr* expr = (Expr*)iter->next();
|
||||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
ExprResult* exprResult = expr->evaluate(aContext);
|
||||||
exprResult->stringValue(result);
|
exprResult->stringValue(result);
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,13 +57,12 @@ BooleanExpr::~BooleanExpr() {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* BooleanExpr::evaluate(Node* context, ContextState* cs) {
|
ExprResult* BooleanExpr::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
|
|
||||||
MBool lval = MB_FALSE;
|
MBool lval = MB_FALSE;
|
||||||
ExprResult* exprRes = 0;
|
ExprResult* exprRes = 0;
|
||||||
if ( leftExpr ) {
|
if ( leftExpr ) {
|
||||||
exprRes = leftExpr->evaluate(context, cs);
|
exprRes = leftExpr->evaluate(aContext);
|
||||||
if ( exprRes ) lval = exprRes->booleanValue();
|
if ( exprRes ) lval = exprRes->booleanValue();
|
||||||
delete exprRes;
|
delete exprRes;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +74,7 @@ ExprResult* BooleanExpr::evaluate(Node* context, ContextState* cs) {
|
||||||
|
|
||||||
MBool rval = MB_FALSE;
|
MBool rval = MB_FALSE;
|
||||||
if ( rightExpr ) {
|
if ( rightExpr ) {
|
||||||
exprRes = rightExpr->evaluate(context, cs);
|
exprRes = rightExpr->evaluate(aContext);
|
||||||
if ( exprRes ) rval = exprRes->booleanValue();
|
if ( exprRes ) rval = exprRes->booleanValue();
|
||||||
delete exprRes;
|
delete exprRes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include "FunctionLib.h"
|
#include "FunctionLib.h"
|
||||||
#include "txAtoms.h"
|
#include "txAtoms.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a default BooleanFunctionCall, which always evaluates to False
|
* Creates a default BooleanFunctionCall, which always evaluates to False
|
||||||
|
@ -62,27 +63,26 @@ BooleanFunctionCall::BooleanFunctionCall(BooleanFunctions aType)
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
ExprResult* BooleanFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
ListIterator iter(¶ms);
|
ListIterator iter(¶ms);
|
||||||
|
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case TX_BOOLEAN:
|
case TX_BOOLEAN:
|
||||||
{
|
{
|
||||||
if (!requireParams(1, 1, aCs))
|
if (!requireParams(1, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
return new BooleanResult(evaluateToBoolean((Expr*)iter.next(),
|
return new BooleanResult(evaluateToBoolean((Expr*)iter.next(),
|
||||||
aContext,
|
aContext));
|
||||||
aCs));
|
|
||||||
}
|
}
|
||||||
case TX_LANG:
|
case TX_LANG:
|
||||||
{
|
{
|
||||||
if (!requireParams(1, 1, aCs))
|
if (!requireParams(1, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String lang;
|
String lang;
|
||||||
Node* node = aContext;
|
Node* node = aContext->getContextNode();
|
||||||
while (node) {
|
while (node) {
|
||||||
if (node->getNodeType() == Node::ELEMENT_NODE) {
|
if (node->getNodeType() == Node::ELEMENT_NODE) {
|
||||||
Element* elem = (Element*)node;
|
Element* elem = (Element*)node;
|
||||||
|
@ -96,7 +96,7 @@ ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
MBool result = MB_FALSE;
|
MBool result = MB_FALSE;
|
||||||
if (node) {
|
if (node) {
|
||||||
String arg;
|
String arg;
|
||||||
evaluateToString((Expr*)iter.next(),aContext, aCs, arg);
|
evaluateToString((Expr*)iter.next(), aContext, arg);
|
||||||
arg.toUpperCase(); // case-insensitive comparison
|
arg.toUpperCase(); // case-insensitive comparison
|
||||||
lang.toUpperCase();
|
lang.toUpperCase();
|
||||||
result = lang.indexOf(arg) == 0 &&
|
result = lang.indexOf(arg) == 0 &&
|
||||||
|
@ -108,23 +108,22 @@ ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case TX_NOT:
|
case TX_NOT:
|
||||||
{
|
{
|
||||||
if (!requireParams(1, 1, aCs))
|
if (!requireParams(1, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
return new BooleanResult(!evaluateToBoolean((Expr*)iter.next(),
|
return new BooleanResult(!evaluateToBoolean((Expr*)iter.next(),
|
||||||
aContext,
|
aContext));
|
||||||
aCs));
|
|
||||||
}
|
}
|
||||||
case TX_TRUE:
|
case TX_TRUE:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 0, aCs))
|
if (!requireParams(0, 0, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
return new BooleanResult(MB_TRUE);
|
return new BooleanResult(MB_TRUE);
|
||||||
}
|
}
|
||||||
case TX_FALSE:
|
case TX_FALSE:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 0, aCs))
|
if (!requireParams(0, 0, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
return new BooleanResult(MB_FALSE);
|
return new BooleanResult(MB_FALSE);
|
||||||
|
@ -132,7 +131,7 @@ ExprResult* BooleanFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
|
|
||||||
String err("Internal error");
|
String err("Internal error");
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#ifndef TRANSFRMX_EXPR_H
|
#ifndef TRANSFRMX_EXPR_H
|
||||||
#define TRANSFRMX_EXPR_H
|
#define TRANSFRMX_EXPR_H
|
||||||
|
|
||||||
|
#include "txError.h"
|
||||||
#include "TxString.h"
|
#include "TxString.h"
|
||||||
#include "ErrorObserver.h"
|
#include "ErrorObserver.h"
|
||||||
#include "NodeSet.h"
|
#include "NodeSet.h"
|
||||||
|
@ -50,51 +50,12 @@
|
||||||
Much of this code was ported from XSL:P.
|
Much of this code was ported from XSL:P.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//necessary prototypes
|
/*
|
||||||
class FunctionCall;
|
* necessary prototypes
|
||||||
|
*/
|
||||||
typedef class Expr Pattern;
|
class txIParseContext;
|
||||||
typedef class Expr PatternExpr;
|
class txIMatchContext;
|
||||||
|
class txIEvalContext;
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Base Class for all XSL Expressions
|
* A Base Class for all XSL Expressions
|
||||||
|
@ -106,7 +67,9 @@ public:
|
||||||
/**
|
/**
|
||||||
* Virtual destructor, important for subclasses
|
* Virtual destructor, important for subclasses
|
||||||
**/
|
**/
|
||||||
virtual ~Expr();
|
virtual ~Expr()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates this Expr based on the given context node and processor state
|
* Evaluates this Expr based on the given context node and processor state
|
||||||
|
@ -115,19 +78,7 @@ public:
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0;
|
virtual ExprResult* evaluate(txIEvalContext* aContext) = 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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the String representation of this Expr.
|
* Returns the String representation of this Expr.
|
||||||
|
@ -141,6 +92,14 @@ public:
|
||||||
|
|
||||||
}; //-- Expr
|
}; //-- 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
|
* This class represents a FunctionCall as defined by the XPath 1.0
|
||||||
* Recommendation.
|
* Recommendation.
|
||||||
|
@ -157,22 +116,22 @@ public:
|
||||||
/**
|
/**
|
||||||
* Virtual methods from Expr
|
* Virtual methods from Expr
|
||||||
**/
|
**/
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0;
|
virtual ExprResult* evaluate(txIEvalContext* aContext) = 0;
|
||||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
|
||||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& dest);
|
virtual void toString(String& dest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the given parameter to this FunctionCall's parameter list
|
* Adds the given parameter to this FunctionCall's parameter list
|
||||||
* @param expr the Expr to add 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);
|
/*
|
||||||
|
* XXX txIEvalContext should be txIParseContest, bug 143291
|
||||||
virtual MBool requireParams(int paramCountMin,
|
*/
|
||||||
int paramCountMax,
|
virtual MBool requireParams(int aParamCountMin, txIEvalContext* aContext);
|
||||||
ContextState* cs);
|
virtual MBool requireParams(int aParamCountMin,
|
||||||
|
int aParamCountMax,
|
||||||
|
txIEvalContext* aContext);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -185,24 +144,24 @@ protected:
|
||||||
* Evaluates the given Expression and converts its result to a String.
|
* Evaluates the given Expression and converts its result to a String.
|
||||||
* The value is appended to the given destination String
|
* The value is appended to the given destination String
|
||||||
*/
|
*/
|
||||||
void evaluateToString(Expr* aExpr, Node* aContext,
|
void evaluateToString(Expr* aExpr, txIEvalContext* aContext,
|
||||||
ContextState* aCs, String& aDest);
|
String& aDest);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Evaluates the given Expression and converts its result to a number.
|
* 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.
|
* 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.
|
* Evaluates the given Expression and converts its result to a NodeSet.
|
||||||
* If the result is not a NodeSet NULL is returned.
|
* 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;
|
String name;
|
||||||
}; //-- FunctionCall
|
}; //-- FunctionCall
|
||||||
|
@ -224,172 +183,91 @@ public:
|
||||||
**/
|
**/
|
||||||
void addExpr(Expr* expr);
|
void addExpr(Expr* expr);
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
List expressions;
|
List expressions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* This class represents a NodeTestExpr as defined by the XSL
|
* This class represents a NodeTest as defined by the XPath spec
|
||||||
* Working Draft
|
*/
|
||||||
**/
|
class txNodeTest
|
||||||
class NodeExpr : public Expr {
|
{
|
||||||
|
|
||||||
public:
|
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
|
#define TX_DECL_NODE_TEST \
|
||||||
//-- LF - changed from const short to enum
|
MBool matches(Node* aNode, txIMatchContext* aContext); \
|
||||||
enum NodeExprType {
|
double getDefaultPriority(); \
|
||||||
ATTRIBUTE_EXPR = 1,
|
void toString(String& aDest)
|
||||||
ELEMENT_EXPR,
|
|
||||||
TEXT_EXPR,
|
/*
|
||||||
COMMENT_EXPR,
|
* This class represents a NameTest as defined by the XPath spec
|
||||||
PI_EXPR,
|
*/
|
||||||
NODE_EXPR
|
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);
|
||||||
|
|
||||||
//------------------/
|
~txNodeTypeTest();
|
||||||
//- Public Methods -/
|
|
||||||
//------------------/
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* 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
|
* Sets the name of the node to match. Only availible for pi nodes
|
||||||
**/
|
*/
|
||||||
void setNodeName(const String& name);
|
void setNodeName(const String& aName);
|
||||||
|
|
||||||
/**
|
TX_DECL_NODE_TEST;
|
||||||
* 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:
|
private:
|
||||||
NodeExprType type;
|
NodeType mNodeType;
|
||||||
String nodeName;
|
txAtom* mNodeName;
|
||||||
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
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an ordered list of Predicates,
|
* Represents an ordered list of Predicates,
|
||||||
|
@ -415,8 +293,7 @@ public:
|
||||||
**/
|
**/
|
||||||
void add(Expr* expr);
|
void add(Expr* expr);
|
||||||
|
|
||||||
|
void evaluatePredicates(NodeSet* aNodes, txIMatchContext* aContext);
|
||||||
void evaluatePredicates(NodeSet* nodes, ContextState* cs);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns true if this predicate list is empty
|
* returns true if this predicate list is empty
|
||||||
|
@ -433,7 +310,7 @@ public:
|
||||||
**/
|
**/
|
||||||
virtual void toString(String& dest);
|
virtual void toString(String& dest);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
//-- list of predicates
|
//-- list of predicates
|
||||||
List predicates;
|
List predicates;
|
||||||
}; //-- PredicateList
|
}; //-- PredicateList
|
||||||
|
@ -444,7 +321,7 @@ public:
|
||||||
|
|
||||||
// Axis Identifier Types
|
// Axis Identifier Types
|
||||||
//-- LF changed from static const short to enum
|
//-- LF changed from static const short to enum
|
||||||
enum _LocationStepType {
|
enum LocationStepType {
|
||||||
ANCESTOR_AXIS = 0,
|
ANCESTOR_AXIS = 0,
|
||||||
ANCESTOR_OR_SELF_AXIS,
|
ANCESTOR_OR_SELF_AXIS,
|
||||||
ATTRIBUTE_AXIS,
|
ATTRIBUTE_AXIS,
|
||||||
|
@ -465,28 +342,24 @@ public:
|
||||||
* @param nodeExpr the NodeExpr to use when matching Nodes
|
* @param nodeExpr the NodeExpr to use when matching Nodes
|
||||||
* @param axisIdentifier the Axis Identifier in which to search for 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
|
* Destructor, will delete all predicates and the given NodeExpr
|
||||||
**/
|
**/
|
||||||
virtual ~LocationStep();
|
virtual ~LocationStep();
|
||||||
|
|
||||||
/**
|
TX_DECL_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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
NodeExpr* nodeExpr;
|
txNodeTest* mNodeTest;
|
||||||
short axisIdentifier;
|
LocationStepType mAxisIdentifier;
|
||||||
|
|
||||||
void fromDescendants(Node* context, ContextState* cs, NodeSet* nodes);
|
void fromDescendants(Node* node, txIMatchContext* aContext,
|
||||||
void fromDescendantsRev(Node* context, ContextState* cs, NodeSet* nodes);
|
NodeSet* nodes);
|
||||||
|
void fromDescendantsRev(Node* node, txIMatchContext* aContext,
|
||||||
|
NodeSet* nodes);
|
||||||
|
|
||||||
}; //-- LocationStep
|
}; //-- LocationStep
|
||||||
|
|
||||||
|
@ -499,20 +372,14 @@ public:
|
||||||
* Creates a new FilterExpr using the given Expr
|
* Creates a new FilterExpr using the given Expr
|
||||||
* @param expr the Expr to use for evaluation
|
* @param expr the Expr to use for evaluation
|
||||||
**/
|
**/
|
||||||
FilterExpr(Expr* expr);
|
FilterExpr(Expr* aExpr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor, will delete all predicates and the given Expr
|
* Destructor, will delete all predicates and the given Expr
|
||||||
**/
|
**/
|
||||||
virtual ~FilterExpr();
|
virtual ~FilterExpr();
|
||||||
|
|
||||||
/**
|
TX_DECL_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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expr* expr;
|
Expr* expr;
|
||||||
|
@ -526,11 +393,7 @@ public:
|
||||||
|
|
||||||
NumberExpr(double dbl);
|
NumberExpr(double dbl);
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -546,11 +409,7 @@ public:
|
||||||
|
|
||||||
StringExpr(const String& value);
|
StringExpr(const String& value);
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -575,11 +434,7 @@ public:
|
||||||
AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||||
~AdditiveExpr();
|
~AdditiveExpr();
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
short op;
|
short op;
|
||||||
|
@ -597,11 +452,7 @@ public:
|
||||||
UnaryExpr(Expr* expr);
|
UnaryExpr(Expr* expr);
|
||||||
~UnaryExpr();
|
~UnaryExpr();
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Expr* expr;
|
Expr* expr;
|
||||||
|
@ -621,11 +472,7 @@ public:
|
||||||
BooleanExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
BooleanExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||||
~BooleanExpr();
|
~BooleanExpr();
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
short op;
|
short op;
|
||||||
|
@ -652,11 +499,7 @@ public:
|
||||||
MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||||
~MultiplicativeExpr();
|
~MultiplicativeExpr();
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
short op;
|
short op;
|
||||||
|
@ -692,11 +535,7 @@ public:
|
||||||
RelationalExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
RelationalExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||||
~RelationalExpr();
|
~RelationalExpr();
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
short op;
|
short op;
|
||||||
|
@ -714,18 +553,16 @@ class VariableRefExpr : public Expr {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
VariableRefExpr(const String& name);
|
VariableRefExpr(txAtom* aPrefix, txAtom* aLocalName, PRInt32 aNSID);
|
||||||
|
~VariableRefExpr();
|
||||||
|
|
||||||
/**
|
TX_DECL_EXPR;
|
||||||
* Virtual methods from Expr
|
|
||||||
**/
|
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
|
||||||
virtual void toString(String& str);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String name;
|
txAtom* mPrefix;
|
||||||
|
txAtom* mLocalName;
|
||||||
}; //-- VariableRefExpr
|
PRInt32 mNamespace;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a PathExpr
|
* Represents a PathExpr
|
||||||
|
@ -755,32 +592,25 @@ public:
|
||||||
**/
|
**/
|
||||||
void addExpr(Expr* expr, PathOperator pathOp);
|
void addExpr(Expr* expr, PathOperator pathOp);
|
||||||
|
|
||||||
/**
|
TX_DECL_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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static const String RTF_INVALID_OP;
|
||||||
|
static const String NODESET_EXPECTED;
|
||||||
struct PathExprItem {
|
struct PathExprItem {
|
||||||
Expr* expr;
|
Expr* expr;
|
||||||
PathOperator pathOp;
|
PathOperator pathOp;
|
||||||
};
|
};
|
||||||
|
|
||||||
List expressions;
|
List expressions;
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Selects from the descendants of the context node
|
* Selects from the descendants of the context node
|
||||||
* all nodes that match the Expr
|
* all nodes that match the Expr
|
||||||
* -- this will be moving to a Utility class
|
*/
|
||||||
**/
|
void evalDescendants(Expr* aStep, Node* aNode,
|
||||||
void evalDescendants(Expr* expr,
|
txIMatchContext* aContext,
|
||||||
Node* context,
|
NodeSet* resNodes);
|
||||||
ContextState* cs,
|
|
||||||
NodeSet* resNodes);
|
|
||||||
|
|
||||||
}; //-- PathExpr
|
}; //-- PathExpr
|
||||||
|
|
||||||
|
@ -797,13 +627,7 @@ public:
|
||||||
*/
|
*/
|
||||||
RootExpr(MBool aSerialize);
|
RootExpr(MBool aSerialize);
|
||||||
|
|
||||||
/**
|
TX_DECL_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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// When a RootExpr is used in a PathExpr it shouldn't be serialized
|
// When a RootExpr is used in a PathExpr it shouldn't be serialized
|
||||||
|
@ -834,13 +658,7 @@ public:
|
||||||
**/
|
**/
|
||||||
void addExpr(Expr* expr);
|
void addExpr(Expr* expr);
|
||||||
|
|
||||||
/**
|
TX_DECL_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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -41,25 +41,16 @@
|
||||||
#include "ExprParser.h"
|
#include "ExprParser.h"
|
||||||
#include "FunctionLib.h"
|
#include "FunctionLib.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
#include "txAtoms.h"
|
||||||
/**
|
#include "txIXPathContext.h"
|
||||||
* Creates a new ExprParser
|
|
||||||
**/
|
|
||||||
ExprParser::ExprParser() {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default Destructor
|
|
||||||
**/
|
|
||||||
ExprParser::~ExprParser() {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an Attribute Value Template using the given value
|
* Creates an Attribute Value Template using the given value
|
||||||
* This should move to XSLProcessor class
|
* This should move to XSLProcessor class
|
||||||
**/
|
**/
|
||||||
AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
||||||
(const String& attValue)
|
(const String& attValue, txIParseContext* aContext)
|
||||||
{
|
{
|
||||||
|
|
||||||
AttributeValueTemplate* avt = new AttributeValueTemplate();
|
AttributeValueTemplate* avt = new AttributeValueTemplate();
|
||||||
|
|
||||||
if (attValue.isEmpty())
|
if (attValue.isEmpty())
|
||||||
|
@ -116,7 +107,8 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
||||||
case '}':
|
case '}':
|
||||||
if (inExpr) {
|
if (inExpr) {
|
||||||
inExpr = MB_FALSE;
|
inExpr = MB_FALSE;
|
||||||
Expr* expr = createExpr(buffer);
|
ExprLexer lexer(buffer);
|
||||||
|
Expr* expr = createExpr(lexer, aContext);
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
delete avt;
|
delete avt;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -154,18 +146,14 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
||||||
|
|
||||||
} //-- createAttributeValueTemplate
|
} //-- createAttributeValueTemplate
|
||||||
|
|
||||||
Expr* ExprParser::createExpr(const String& aExpression)
|
Expr* ExprParser::createExpr(const String& aExpression,
|
||||||
|
txIParseContext* aContext)
|
||||||
{
|
{
|
||||||
ExprLexer lexer(aExpression);
|
ExprLexer lexer(aExpression);
|
||||||
return createExpr(lexer);
|
Expr* expr = createExpr(lexer, aContext);
|
||||||
|
return expr;
|
||||||
} //-- createExpr
|
} //-- createExpr
|
||||||
|
|
||||||
Pattern* ExprParser::createPattern(const String& aPattern)
|
|
||||||
{
|
|
||||||
ExprLexer lexer(aPattern);
|
|
||||||
return createUnionExpr(lexer);
|
|
||||||
} //-- createPatternExpr
|
|
||||||
|
|
||||||
//--------------------/
|
//--------------------/
|
||||||
//- Private Methods -/
|
//- Private Methods -/
|
||||||
//-------------------/
|
//-------------------/
|
||||||
|
@ -221,8 +209,8 @@ Expr* ExprParser::createBinaryExpr (Expr* left, Expr* right, Token* op) {
|
||||||
} //-- createBinaryExpr
|
} //-- createBinaryExpr
|
||||||
|
|
||||||
|
|
||||||
Expr* ExprParser::createExpr(ExprLexer& lexer) {
|
Expr* ExprParser::createExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||||
|
{
|
||||||
MBool done = MB_FALSE;
|
MBool done = MB_FALSE;
|
||||||
|
|
||||||
Expr* expr = 0;
|
Expr* expr = 0;
|
||||||
|
@ -238,7 +226,7 @@ Expr* ExprParser::createExpr(ExprLexer& lexer) {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = createUnionExpr(lexer);
|
expr = createUnionExpr(lexer, aContext);
|
||||||
if (!expr)
|
if (!expr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -299,21 +287,33 @@ Expr* ExprParser::createExpr(ExprLexer& lexer) {
|
||||||
|
|
||||||
} //-- createExpr
|
} //-- createExpr
|
||||||
|
|
||||||
Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
|
Expr* ExprParser::createFilterExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||||
|
{
|
||||||
Token* tok = lexer.nextToken();
|
Token* tok = lexer.nextToken();
|
||||||
|
|
||||||
Expr* expr = 0;
|
Expr* expr = 0;
|
||||||
switch (tok->type) {
|
switch (tok->type) {
|
||||||
case Token::FUNCTION_NAME :
|
case Token::FUNCTION_NAME :
|
||||||
lexer.pushBack();
|
lexer.pushBack();
|
||||||
expr = createFunctionCall(lexer);
|
expr = createFunctionCall(lexer, aContext);
|
||||||
break;
|
break;
|
||||||
case Token::VAR_REFERENCE :
|
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;
|
break;
|
||||||
case Token::L_PAREN:
|
case Token::L_PAREN:
|
||||||
expr = createExpr(lexer);
|
expr = createExpr(lexer, aContext);
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -347,7 +347,7 @@ Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
|
||||||
FilterExpr* filterExpr = new FilterExpr(expr);
|
FilterExpr* filterExpr = new FilterExpr(expr);
|
||||||
|
|
||||||
//-- handle predicates
|
//-- handle predicates
|
||||||
if (!parsePredicates(filterExpr, lexer)) {
|
if (!parsePredicates(filterExpr, lexer, aContext)) {
|
||||||
delete filterExpr;
|
delete filterExpr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -358,8 +358,9 @@ Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
|
||||||
|
|
||||||
} //-- createFilterExpr
|
} //-- createFilterExpr
|
||||||
|
|
||||||
FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) {
|
Expr* ExprParser::createFunctionCall(ExprLexer& lexer,
|
||||||
|
txIParseContext* aContext)
|
||||||
|
{
|
||||||
FunctionCall* fnCall = 0;
|
FunctionCall* fnCall = 0;
|
||||||
|
|
||||||
Token* tok = lexer.nextToken();
|
Token* tok = lexer.nextToken();
|
||||||
|
@ -368,11 +369,11 @@ FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String fnName = tok->value;
|
|
||||||
|
|
||||||
//-- compare function names
|
//-- compare function names
|
||||||
//-- * we should hash these names for speed
|
//-- * we should hash these names for speed
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
if (XPathNames::BOOLEAN_FN.isEqual(tok->value)) {
|
if (XPathNames::BOOLEAN_FN.isEqual(tok->value)) {
|
||||||
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_BOOLEAN);
|
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_BOOLEAN);
|
||||||
}
|
}
|
||||||
|
@ -455,24 +456,44 @@ FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) {
|
||||||
fnCall = new NumberFunctionCall(NumberFunctionCall::FLOOR);
|
fnCall = new NumberFunctionCall(NumberFunctionCall::FLOOR);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//-- Most likely an Extension Function, or error, but it's
|
txAtom *prefix, *lName;
|
||||||
//-- not our job to report an invalid function call here
|
PRInt32 namespaceID;
|
||||||
fnCall = new ExtensionFunctionCall(fnName);
|
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
|
//-- handle parametes
|
||||||
if (!parseParameters(fnCall, lexer)) {
|
if (!parseParameters(fnCall, lexer, aContext)) {
|
||||||
delete fnCall;
|
delete fnCall;
|
||||||
return 0;
|
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;
|
return fnCall;
|
||||||
} //-- createFunctionCall
|
} //-- createFunctionCall
|
||||||
|
|
||||||
LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) {
|
LocationStep* ExprParser::createLocationStep(ExprLexer& lexer,
|
||||||
|
txIParseContext* aContext)
|
||||||
|
{
|
||||||
//-- child axis is default
|
//-- child axis is default
|
||||||
short axisIdentifier = LocationStep::CHILD_AXIS;
|
LocationStep::LocationStepType axisIdentifier = LocationStep::CHILD_AXIS;
|
||||||
NodeExpr* nodeExpr = 0;
|
txNodeTest* nodeTest = 0;
|
||||||
|
|
||||||
//-- get Axis Identifier or AbbreviatedStep, if present
|
//-- get Axis Identifier or AbbreviatedStep, if present
|
||||||
Token* tok = lexer.peek();
|
Token* tok = lexer.peek();
|
||||||
|
@ -536,44 +557,78 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) {
|
||||||
//-- eat token
|
//-- eat token
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
axisIdentifier = LocationStep::PARENT_AXIS;
|
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;
|
break;
|
||||||
case Token::SELF_NODE :
|
case Token::SELF_NODE :
|
||||||
//-- eat token
|
//-- eat token
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
axisIdentifier = LocationStep::SELF_AXIS;
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-- get NodeTest unless AbbreviatedStep was found
|
//-- get NodeTest unless an AbbreviatedStep was found
|
||||||
if (!nodeExpr) {
|
if (!nodeTest) {
|
||||||
tok = lexer.nextToken();
|
tok = lexer.nextToken();
|
||||||
|
|
||||||
switch (tok->type) {
|
switch (tok->type) {
|
||||||
case Token::CNAME :
|
case Token::CNAME :
|
||||||
// NameTest
|
{
|
||||||
// XXX Namespace: handle namespaces here
|
// resolve QName
|
||||||
if (axisIdentifier == LocationStep::ATTRIBUTE_AXIS)
|
txAtom *prefix, *lName;
|
||||||
nodeExpr = new AttributeExpr(tok->value);
|
PRInt32 nspace;
|
||||||
else
|
nsresult rv = resolveQName(tok->value, prefix, aContext,
|
||||||
nodeExpr = new ElementExpr(tok->value);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
lexer.pushBack();
|
lexer.pushBack();
|
||||||
nodeExpr = createNodeExpr(lexer);
|
nodeTest = createNodeTypeTest(lexer);
|
||||||
if (!nodeExpr) {
|
if (!nodeTest) {
|
||||||
return 0;
|
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
|
//-- handle predicates
|
||||||
if (!parsePredicates(lstep, lexer)) {
|
if (!parsePredicates(lstep, lexer, aContext)) {
|
||||||
delete lstep;
|
delete lstep;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -585,59 +640,62 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) {
|
||||||
* This method only handles comment(), text(), processing-instructing() and node()
|
* 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();
|
Token* nodeTok = lexer.nextToken();
|
||||||
|
|
||||||
switch (nodeTok->type) {
|
switch (nodeTok->type) {
|
||||||
case Token::COMMENT:
|
case Token::COMMENT:
|
||||||
nodeExpr = new BasicNodeExpr(NodeExpr::COMMENT_EXPR);
|
nodeTest = new txNodeTypeTest(txNodeTypeTest::COMMENT_TYPE);
|
||||||
break;
|
break;
|
||||||
case Token::NODE :
|
case Token::NODE :
|
||||||
nodeExpr = new BasicNodeExpr(NodeExpr::NODE_EXPR);
|
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||||
break;
|
break;
|
||||||
case Token::PROC_INST :
|
case Token::PROC_INST :
|
||||||
nodeExpr = new BasicNodeExpr(NodeExpr::PI_EXPR);
|
nodeTest = new txNodeTypeTest(txNodeTypeTest::PI_TYPE);
|
||||||
break;
|
break;
|
||||||
case Token::TEXT :
|
case Token::TEXT :
|
||||||
nodeExpr = new TextExpr();
|
nodeTest = new txNodeTypeTest(txNodeTypeTest::TEXT_TYPE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
lexer.pushBack();
|
lexer.pushBack();
|
||||||
// XXX ErrorReport: unexpected token
|
// XXX ErrorReport: unexpected token
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
}
|
||||||
|
if (!nodeTest) {
|
||||||
|
//XXX out of memory
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lexer.nextToken()->type != Token::L_PAREN) {
|
if (lexer.nextToken()->type != Token::L_PAREN) {
|
||||||
lexer.pushBack();
|
lexer.pushBack();
|
||||||
//XXX ErrorReport: left parenthesis expected
|
//XXX ErrorReport: left parenthesis expected
|
||||||
delete nodeExpr;
|
delete nodeTest;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (nodeTok->type == Token::PROC_INST &&
|
if (nodeTok->type == Token::PROC_INST &&
|
||||||
lexer.peek()->type == Token::LITERAL) {
|
lexer.peek()->type == Token::LITERAL) {
|
||||||
Token* tok = lexer.nextToken();
|
Token* tok = lexer.nextToken();
|
||||||
((BasicNodeExpr*)nodeExpr)->setNodeName(tok->value);
|
nodeTest->setNodeName(tok->value);
|
||||||
}
|
}
|
||||||
if (lexer.nextToken()->type != Token::R_PAREN) {
|
if (lexer.nextToken()->type != Token::R_PAREN) {
|
||||||
lexer.pushBack();
|
lexer.pushBack();
|
||||||
//XXX ErrorReport: right parenthesis expected (or literal for pi)
|
//XXX ErrorReport: right parenthesis expected (or literal for pi)
|
||||||
delete nodeExpr;
|
delete nodeTest;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeExpr;
|
return nodeTest;
|
||||||
} //-- createNodeExpr
|
} //-- createNodeTypeTest
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a PathExpr using the given ExprLexer
|
* Creates a PathExpr using the given ExprLexer
|
||||||
* @param lexer the ExprLexer for retrieving Tokens
|
* @param lexer the ExprLexer for retrieving Tokens
|
||||||
**/
|
**/
|
||||||
Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
Expr* ExprParser::createPathExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||||
|
{
|
||||||
Expr* expr = 0;
|
Expr* expr = 0;
|
||||||
|
|
||||||
Token* tok = lexer.peek();
|
Token* tok = lexer.peek();
|
||||||
|
@ -655,10 +713,10 @@ Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
||||||
if (tok->type != Token::PARENT_OP &&
|
if (tok->type != Token::PARENT_OP &&
|
||||||
tok->type != Token::ANCESTOR_OP) {
|
tok->type != Token::ANCESTOR_OP) {
|
||||||
if (isFilterExprToken(tok)) {
|
if (isFilterExprToken(tok)) {
|
||||||
expr = createFilterExpr(lexer);
|
expr = createFilterExpr(lexer, aContext);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
expr = createLocationStep(lexer);
|
expr = createLocationStep(lexer, aContext);
|
||||||
|
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -702,7 +760,7 @@ Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
||||||
return pathExpr;
|
return pathExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = createLocationStep(lexer);
|
expr = createLocationStep(lexer, aContext);
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
delete pathExpr;
|
delete pathExpr;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -719,9 +777,9 @@ Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
||||||
* XXX temporary use as top of XSLT Pattern
|
* XXX temporary use as top of XSLT Pattern
|
||||||
* @param lexer the ExprLexer for retrieving Tokens
|
* @param lexer the ExprLexer for retrieving Tokens
|
||||||
**/
|
**/
|
||||||
Expr* ExprParser::createUnionExpr(ExprLexer& lexer) {
|
Expr* ExprParser::createUnionExpr(ExprLexer& lexer, txIParseContext* aContext)
|
||||||
|
{
|
||||||
Expr* expr = createPathExpr(lexer);
|
Expr* expr = createPathExpr(lexer, aContext);
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -734,7 +792,7 @@ Expr* ExprParser::createUnionExpr(ExprLexer& lexer) {
|
||||||
while (lexer.peek()->type == Token::UNION_OP) {
|
while (lexer.peek()->type == Token::UNION_OP) {
|
||||||
lexer.nextToken(); //-- eat token
|
lexer.nextToken(); //-- eat token
|
||||||
|
|
||||||
expr = createPathExpr(lexer);
|
expr = createPathExpr(lexer, aContext);
|
||||||
if (!expr) {
|
if (!expr) {
|
||||||
delete unionExpr;
|
delete unionExpr;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -791,13 +849,14 @@ MBool ExprParser::isNodeTypeToken(Token* token) {
|
||||||
* @param lexer the ExprLexer to use for parsing tokens
|
* @param lexer the ExprLexer to use for parsing tokens
|
||||||
* @return 0 if successful, or a String pointer to the error message
|
* @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) {
|
while (lexer.peek()->type == Token::L_BRACKET) {
|
||||||
//-- eat Token
|
//-- eat Token
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
|
||||||
Expr* expr = createExpr(lexer);
|
Expr* expr = createExpr(lexer, aContext);
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return MB_FALSE;
|
return MB_FALSE;
|
||||||
|
|
||||||
|
@ -822,8 +881,9 @@ MBool ExprParser::parsePredicates(PredicateList* predicateList, ExprLexer& lexer
|
||||||
* @param lexer the ExprLexer to use for parsing tokens
|
* @param lexer the ExprLexer to use for parsing tokens
|
||||||
* @return MB_TRUE if successful, or a MB_FALSE otherwise
|
* @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) {
|
if (lexer.nextToken()->type != Token::L_PAREN) {
|
||||||
lexer.pushBack();
|
lexer.pushBack();
|
||||||
//XXX ErrorReport: left parenthesis expected
|
//XXX ErrorReport: left parenthesis expected
|
||||||
|
@ -836,11 +896,12 @@ MBool ExprParser::parseParameters(FunctionCall* fnCall, ExprLexer& lexer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
Expr* expr = createExpr(lexer);
|
Expr* expr = createExpr(lexer, aContext);
|
||||||
if (!expr)
|
if (!expr)
|
||||||
return MB_FALSE;
|
return MB_FALSE;
|
||||||
|
|
||||||
fnCall->addParam(expr);
|
if (fnCall)
|
||||||
|
fnCall->addParam(expr);
|
||||||
|
|
||||||
switch (lexer.nextToken()->type) {
|
switch (lexer.nextToken()->type) {
|
||||||
case Token::R_PAREN :
|
case Token::R_PAREN :
|
||||||
|
@ -887,5 +948,35 @@ short ExprParser::precedenceLevel(short tokenType) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
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 "ExprLexer.h"
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
#include "List.h"
|
#include "List.h"
|
||||||
|
class txIParseContext;
|
||||||
|
|
||||||
class ExprParser {
|
class ExprParser
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
static Expr* createExpr(const String& aExpression,
|
||||||
* Creates a new ExprParser
|
txIParseContext* aContext);
|
||||||
**/
|
|
||||||
ExprParser();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* destroys the ExprParser
|
|
||||||
**/
|
|
||||||
~ExprParser();
|
|
||||||
|
|
||||||
Expr* createExpr(const String& aExpression);
|
|
||||||
Pattern* createPattern(const String& aPattern);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an Attribute Value Template using the given value
|
* Creates an Attribute Value Template using the given value
|
||||||
**/
|
**/
|
||||||
AttributeValueTemplate* createAttributeValueTemplate(const String& attValue);
|
static AttributeValueTemplate* createAttributeValueTemplate
|
||||||
|
(const String& attValue, txIParseContext* aContext);
|
||||||
|
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
static Expr* createBinaryExpr(Expr* left, Expr* right, Token* op);
|
||||||
|
static Expr* createExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||||
Expr* createBinaryExpr (Expr* left, Expr* right, Token* op);
|
static Expr* createFilterExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||||
Expr* createExpr (ExprLexer& lexer);
|
static Expr* createFunctionCall(ExprLexer& lexer,
|
||||||
Expr* createFilterExpr (ExprLexer& lexer);
|
txIParseContext* aContext);
|
||||||
FunctionCall* createFunctionCall (ExprLexer& lexer);
|
static LocationStep* createLocationStep(ExprLexer& lexer,
|
||||||
LocationStep* createLocationStep (ExprLexer& lexer);
|
txIParseContext* aContext);
|
||||||
NodeExpr* createNodeExpr (ExprLexer& lexer);
|
static txNodeTypeTest* createNodeTypeTest(ExprLexer& lexer);
|
||||||
Expr* createPathExpr (ExprLexer& lexer);
|
static Expr* createPathExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||||
Expr* createUnionExpr (ExprLexer& lexer);
|
static Expr* createUnionExpr(ExprLexer& lexer, txIParseContext* aContext);
|
||||||
|
|
||||||
MBool isFilterExprToken (Token* tok);
|
static MBool isFilterExprToken (Token* tok);
|
||||||
MBool isLocationStepToken (Token* tok);
|
static MBool isLocationStepToken(Token* tok);
|
||||||
MBool isNodeTypeToken (Token* tok);
|
static MBool isNodeTypeToken (Token* tok);
|
||||||
|
|
||||||
static short precedenceLevel (short tokenType);
|
static short precedenceLevel (short tokenType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Using the given lexer, parses the tokens if they represent a predicate list
|
* Resolve a QName, given the mContext parse context.
|
||||||
* If an error occurs a non-zero String pointer will be returned containing the
|
* Returns prefix and localName as well as namespace ID
|
||||||
* error message.
|
**/
|
||||||
|
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 predicateList, the PredicateList to add predicate expressions to
|
||||||
* @param lexer the ExprLexer to use for parsing tokens
|
* @param lexer the ExprLexer to use for parsing tokens
|
||||||
* @return 0 if successful, or a String pointer to the error message
|
* @return 0 if successful, or a String pointer to the error message
|
||||||
**/
|
**/
|
||||||
MBool parsePredicates(PredicateList* predicateList, ExprLexer& lexer);
|
static MBool parsePredicates(PredicateList* predicateList,
|
||||||
MBool parseParameters(FunctionCall* fnCall, ExprLexer& lexer);
|
ExprLexer& lexer, txIParseContext* aContext);
|
||||||
|
static MBool parseParameters(FunctionCall* fnCall,
|
||||||
|
ExprLexer& lexer, txIParseContext* aContext);
|
||||||
|
|
||||||
}; //-- ExprParser
|
}; //-- ExprParser
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
//-- Implementation of FilterExpr --/
|
//-- Implementation of FilterExpr --/
|
||||||
|
|
||||||
|
@ -56,24 +57,24 @@ FilterExpr::~FilterExpr() {
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see Expr
|
* @see Expr
|
||||||
**/
|
**/
|
||||||
ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) {
|
ExprResult* FilterExpr::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
if (!context || !expr)
|
if (!aContext || !expr)
|
||||||
return new NodeSet;
|
return new NodeSet;
|
||||||
|
|
||||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
ExprResult* exprResult = expr->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||||
// Result is a nodeset, filter it.
|
// Result is a nodeset, filter it.
|
||||||
evaluatePredicates((NodeSet*)exprResult, cs);
|
evaluatePredicates((NodeSet*)exprResult, aContext);
|
||||||
}
|
}
|
||||||
else if(!isEmpty()) {
|
else if(!isEmpty()) {
|
||||||
// We can't filter a non-nodeset
|
// We can't filter a non-nodeset
|
||||||
String err("Expecting nodeset as result of: ");
|
String err("Expecting nodeset as result of: ");
|
||||||
expr->toString(err);
|
expr->toString(err);
|
||||||
cs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_XPATH_EVAL_FAILED);
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
return new NodeSet;
|
return new NodeSet;
|
||||||
}
|
}
|
||||||
|
@ -81,40 +82,6 @@ ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) {
|
||||||
return exprResult;
|
return exprResult;
|
||||||
} //-- evaluate
|
} //-- 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
|
* Creates a String representation of this Expr
|
||||||
* @param str the destination String to append to
|
* @param str the destination String to append to
|
||||||
|
|
|
@ -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
|
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class represents a FunctionCall as defined by the XSL Working Draft
|
* 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
|
* Adds the given parameter to this FunctionCall's parameter list
|
||||||
* @param expr the Expr to add 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)
|
if (aExpr)
|
||||||
params.add(expr);
|
params.add(aExpr);
|
||||||
|
return NS_OK;
|
||||||
} //-- addParam
|
} //-- 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.
|
* Evaluates the given Expression and converts its result to a String.
|
||||||
* The value is appended to the given destination String
|
* The value is appended to the given destination String
|
||||||
*/
|
*/
|
||||||
void FunctionCall::evaluateToString(Expr* aExpr,
|
void FunctionCall::evaluateToString(Expr* aExpr, txIEvalContext* aContext,
|
||||||
Node* aContext,
|
|
||||||
ContextState* aCs,
|
|
||||||
String& aDest)
|
String& aDest)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aExpr, "missing expression");
|
NS_ASSERTION(aExpr, "missing expression");
|
||||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -131,12 +104,10 @@ void FunctionCall::evaluateToString(Expr* aExpr,
|
||||||
/*
|
/*
|
||||||
* Evaluates the given Expression and converts its result to a number.
|
* Evaluates the given Expression and converts its result to a number.
|
||||||
*/
|
*/
|
||||||
double FunctionCall::evaluateToNumber(Expr* aExpr,
|
double FunctionCall::evaluateToNumber(Expr* aExpr, txIEvalContext* aContext)
|
||||||
Node* aContext,
|
|
||||||
ContextState* aCs)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aExpr, "missing expression");
|
NS_ASSERTION(aExpr, "missing expression");
|
||||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return Double::NaN;
|
return Double::NaN;
|
||||||
|
|
||||||
|
@ -148,12 +119,10 @@ double FunctionCall::evaluateToNumber(Expr* aExpr,
|
||||||
/*
|
/*
|
||||||
* Evaluates the given Expression and converts its result to a boolean.
|
* Evaluates the given Expression and converts its result to a boolean.
|
||||||
*/
|
*/
|
||||||
MBool FunctionCall::evaluateToBoolean(Expr* aExpr,
|
MBool FunctionCall::evaluateToBoolean(Expr* aExpr, txIEvalContext* aContext)
|
||||||
Node* aContext,
|
|
||||||
ContextState* aCs)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aExpr, "missing expression");
|
NS_ASSERTION(aExpr, "missing expression");
|
||||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return MB_FALSE;
|
return MB_FALSE;
|
||||||
|
|
||||||
|
@ -166,18 +135,16 @@ MBool FunctionCall::evaluateToBoolean(Expr* aExpr,
|
||||||
* Evaluates the given Expression and converts its result to a NodeSet.
|
* Evaluates the given Expression and converts its result to a NodeSet.
|
||||||
* If the result is not a NodeSet NULL is returned.
|
* If the result is not a NodeSet NULL is returned.
|
||||||
*/
|
*/
|
||||||
NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr,
|
NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr, txIEvalContext* aContext)
|
||||||
Node* aContext,
|
|
||||||
ContextState* aCs)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aExpr, "Missing expression to evaluate");
|
NS_ASSERTION(aExpr, "Missing expression to evaluate");
|
||||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
ExprResult* exprResult = aExpr->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (exprResult->getResultType() != ExprResult::NODESET) {
|
if (exprResult->getResultType() != ExprResult::NODESET) {
|
||||||
String err("NodeSet expected as argument");
|
String err("NodeSet expected as argument");
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -190,13 +157,13 @@ NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr,
|
||||||
**/
|
**/
|
||||||
MBool FunctionCall::requireParams (int paramCountMin,
|
MBool FunctionCall::requireParams (int paramCountMin,
|
||||||
int paramCountMax,
|
int paramCountMax,
|
||||||
ContextState* cs)
|
txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
int argc = params.getLength();
|
int argc = params.getLength();
|
||||||
if ((argc < paramCountMin) || (argc > paramCountMax)) {
|
if ((argc < paramCountMin) || (argc > paramCountMax)) {
|
||||||
String err(INVALID_PARAM_COUNT);
|
String err(INVALID_PARAM_COUNT);
|
||||||
toString(err);
|
toString(err);
|
||||||
cs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
return MB_FALSE;
|
return MB_FALSE;
|
||||||
}
|
}
|
||||||
return MB_TRUE;
|
return MB_TRUE;
|
||||||
|
@ -205,13 +172,13 @@ MBool FunctionCall::requireParams (int paramCountMin,
|
||||||
/**
|
/**
|
||||||
* Called to check number of parameters
|
* Called to check number of parameters
|
||||||
**/
|
**/
|
||||||
MBool FunctionCall::requireParams(int paramCountMin, ContextState* cs)
|
MBool FunctionCall::requireParams(int paramCountMin, txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
int argc = params.getLength();
|
int argc = params.getLength();
|
||||||
if (argc < paramCountMin) {
|
if (argc < paramCountMin) {
|
||||||
String err(INVALID_PARAM_COUNT);
|
String err(INVALID_PARAM_COUNT);
|
||||||
toString(err);
|
toString(err);
|
||||||
cs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
return MB_FALSE;
|
return MB_FALSE;
|
||||||
}
|
}
|
||||||
return MB_TRUE;
|
return MB_TRUE;
|
||||||
|
|
|
@ -125,14 +125,7 @@ public:
|
||||||
**/
|
**/
|
||||||
BooleanFunctionCall(BooleanFunctions aType);
|
BooleanFunctionCall(BooleanFunctions aType);
|
||||||
|
|
||||||
/**
|
TX_DECL_EVALUATE;
|
||||||
* 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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BooleanFunctions mType;
|
BooleanFunctions mType;
|
||||||
|
@ -148,14 +141,7 @@ public:
|
||||||
ErrorFunctionCall();
|
ErrorFunctionCall();
|
||||||
ErrorFunctionCall(const String& errorMsg);
|
ErrorFunctionCall(const String& errorMsg);
|
||||||
|
|
||||||
/**
|
TX_DECL_EVALUATE;
|
||||||
* 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);
|
|
||||||
|
|
||||||
void setErrorMessage(String& errorMsg);
|
void setErrorMessage(String& errorMsg);
|
||||||
|
|
||||||
|
@ -165,89 +151,6 @@ private:
|
||||||
|
|
||||||
}; //-- ErrorFunctionCall
|
}; //-- 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
|
* A representation of the XPath NodeSet funtions
|
||||||
*/
|
*/
|
||||||
|
@ -270,14 +173,7 @@ public:
|
||||||
*/
|
*/
|
||||||
NodeSetFunctionCall(NodeSetFunctions aType);
|
NodeSetFunctionCall(NodeSetFunctions aType);
|
||||||
|
|
||||||
/*
|
TX_DECL_EVALUATE;
|
||||||
* 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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NodeSetFunctions mType;
|
NodeSetFunctions mType;
|
||||||
|
@ -309,14 +205,7 @@ public:
|
||||||
**/
|
**/
|
||||||
StringFunctionCall(StringFunctions aType);
|
StringFunctionCall(StringFunctions aType);
|
||||||
|
|
||||||
/**
|
TX_DECL_EVALUATE;
|
||||||
* 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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StringFunctions mType;
|
StringFunctions mType;
|
||||||
|
@ -343,14 +232,7 @@ public:
|
||||||
*/
|
*/
|
||||||
NumberFunctionCall(NumberFunctions aType);
|
NumberFunctionCall(NumberFunctions aType);
|
||||||
|
|
||||||
/*
|
TX_DECL_EVALUATE;
|
||||||
* 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);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NumberFunctions mType;
|
NumberFunctions mType;
|
||||||
|
|
|
@ -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
|
|
@ -28,15 +28,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new LocationStep using the given NodeExpr and Axis Identifier
|
* Creates a new LocationStep using the given NodeExpr and Axis Identifier
|
||||||
* @param nodeExpr the NodeExpr to use when matching Nodes
|
* @param nodeExpr the NodeExpr to use when matching Nodes
|
||||||
* @param axisIdentifier the Axis Identifier in which to search for nodes
|
* @param axisIdentifier the Axis Identifier in which to search for nodes
|
||||||
**/
|
**/
|
||||||
LocationStep::LocationStep(NodeExpr* nodeExpr, short axisIdentifier) : PredicateList() {
|
LocationStep::LocationStep(txNodeTest* aNodeTest,
|
||||||
this->nodeExpr = nodeExpr;
|
LocationStepType aAxisIdentifier)
|
||||||
this->axisIdentifier = axisIdentifier;
|
: mNodeTest(aNodeTest), mAxisIdentifier(aAxisIdentifier)
|
||||||
|
{
|
||||||
} //-- LocationStep
|
} //-- LocationStep
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +47,7 @@ LocationStep::LocationStep(NodeExpr* nodeExpr, short axisIdentifier) : Predicate
|
||||||
* The NodeExpr will be deleted
|
* The NodeExpr will be deleted
|
||||||
**/
|
**/
|
||||||
LocationStep::~LocationStep() {
|
LocationStep::~LocationStep() {
|
||||||
delete nodeExpr;
|
delete mNodeTest;
|
||||||
} //-- ~LocationStep
|
} //-- ~LocationStep
|
||||||
|
|
||||||
//-----------------------------/
|
//-----------------------------/
|
||||||
|
@ -60,23 +62,25 @@ LocationStep::~LocationStep() {
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see Expr
|
* @see Expr
|
||||||
**/
|
**/
|
||||||
ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
ExprResult* LocationStep::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aContext, "internal error");
|
||||||
|
|
||||||
NodeSet* nodes = new NodeSet();
|
NodeSet* nodes = new NodeSet();
|
||||||
if (!context || !nodeExpr || !nodes)
|
if (!nodes)
|
||||||
return nodes;
|
return 0;
|
||||||
|
|
||||||
MBool reverse = MB_FALSE;
|
MBool reverse = MB_FALSE;
|
||||||
|
|
||||||
Node* node = context;
|
Node* node = aContext->getContextNode();
|
||||||
switch (axisIdentifier) {
|
switch (mAxisIdentifier) {
|
||||||
case ANCESTOR_AXIS :
|
case ANCESTOR_AXIS :
|
||||||
node = context->getXPathParent();
|
node = node->getXPathParent();
|
||||||
//-- do not break here
|
//-- do not break here
|
||||||
case ANCESTOR_OR_SELF_AXIS :
|
case ANCESTOR_OR_SELF_AXIS :
|
||||||
reverse = MB_TRUE;
|
reverse = MB_TRUE;
|
||||||
while (node) {
|
while (node) {
|
||||||
if (nodeExpr->matches(node, context, cs)) {
|
if (mNodeTest->matches(node, aContext)) {
|
||||||
nodes->append(node);
|
nodes->append(node);
|
||||||
}
|
}
|
||||||
node = node->getXPathParent();
|
node = node->getXPathParent();
|
||||||
|
@ -84,28 +88,28 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||||
break;
|
break;
|
||||||
case ATTRIBUTE_AXIS :
|
case ATTRIBUTE_AXIS :
|
||||||
{
|
{
|
||||||
NamedNodeMap* atts = context->getAttributes();
|
NamedNodeMap* atts = node->getAttributes();
|
||||||
if (atts) {
|
if (atts) {
|
||||||
for (PRUint32 i = 0; i < atts->getLength(); i++) {
|
for (PRUint32 i = 0; i < atts->getLength(); i++) {
|
||||||
Node* attr = atts->item(i);
|
Node* attr = atts->item(i);
|
||||||
if (nodeExpr->matches(attr, context, cs))
|
if (mNodeTest->matches(attr, aContext))
|
||||||
nodes->append(attr);
|
nodes->append(attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DESCENDANT_OR_SELF_AXIS :
|
case DESCENDANT_OR_SELF_AXIS :
|
||||||
if (nodeExpr->matches(context, context, cs))
|
if (mNodeTest->matches(node, aContext))
|
||||||
nodes->append(context);
|
nodes->append(node);
|
||||||
//-- do not break here
|
//-- do not break here
|
||||||
case DESCENDANT_AXIS :
|
case DESCENDANT_AXIS :
|
||||||
fromDescendants(context, cs, nodes);
|
fromDescendants(node, aContext, nodes);
|
||||||
break;
|
break;
|
||||||
case FOLLOWING_AXIS :
|
case FOLLOWING_AXIS :
|
||||||
{
|
{
|
||||||
if ( node->getNodeType() == Node::ATTRIBUTE_NODE) {
|
if ( node->getNodeType() == Node::ATTRIBUTE_NODE) {
|
||||||
node = node->getXPathParent();
|
node = node->getXPathParent();
|
||||||
fromDescendants(node, cs, nodes);
|
fromDescendants(node, aContext, nodes);
|
||||||
}
|
}
|
||||||
while (node && !node->getNextSibling()) {
|
while (node && !node->getNextSibling()) {
|
||||||
node = node->getXPathParent();
|
node = node->getXPathParent();
|
||||||
|
@ -113,11 +117,11 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||||
while (node) {
|
while (node) {
|
||||||
node = node->getNextSibling();
|
node = node->getNextSibling();
|
||||||
|
|
||||||
if (nodeExpr->matches(node, context, cs))
|
if (mNodeTest->matches(node, aContext))
|
||||||
nodes->append(node);
|
nodes->append(node);
|
||||||
|
|
||||||
if (node->hasChildNodes())
|
if (node->hasChildNodes())
|
||||||
fromDescendants(node, cs, nodes);
|
fromDescendants(node, aContext, nodes);
|
||||||
|
|
||||||
while (node && !node->getNextSibling()) {
|
while (node && !node->getNextSibling()) {
|
||||||
node = node->getParentNode();
|
node = node->getParentNode();
|
||||||
|
@ -126,9 +130,9 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FOLLOWING_SIBLING_AXIS :
|
case FOLLOWING_SIBLING_AXIS :
|
||||||
node = context->getNextSibling();
|
node = node->getNextSibling();
|
||||||
while (node) {
|
while (node) {
|
||||||
if (nodeExpr->matches(node, context, cs))
|
if (mNodeTest->matches(node, aContext))
|
||||||
nodes->append(node);
|
nodes->append(node);
|
||||||
node = node->getNextSibling();
|
node = node->getNextSibling();
|
||||||
}
|
}
|
||||||
|
@ -141,8 +145,8 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||||
break;
|
break;
|
||||||
case PARENT_AXIS :
|
case PARENT_AXIS :
|
||||||
{
|
{
|
||||||
Node* parent = context->getXPathParent();
|
Node* parent = node->getXPathParent();
|
||||||
if ( nodeExpr->matches(parent, context, cs) )
|
if (mNodeTest->matches(parent, aContext))
|
||||||
nodes->append(parent);
|
nodes->append(parent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -155,9 +159,9 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||||
node = node->getPreviousSibling();
|
node = node->getPreviousSibling();
|
||||||
|
|
||||||
if (node->hasChildNodes())
|
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);
|
nodes->append(node);
|
||||||
|
|
||||||
while (node && !node->getPreviousSibling()) {
|
while (node && !node->getPreviousSibling()) {
|
||||||
|
@ -167,56 +171,48 @@ ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||||
break;
|
break;
|
||||||
case PRECEDING_SIBLING_AXIS:
|
case PRECEDING_SIBLING_AXIS:
|
||||||
reverse = MB_TRUE;
|
reverse = MB_TRUE;
|
||||||
node = context->getPreviousSibling();
|
node = node->getPreviousSibling();
|
||||||
while (node) {
|
while (node) {
|
||||||
if (nodeExpr->matches(node, context, cs))
|
if (mNodeTest->matches(node, aContext))
|
||||||
nodes->append(node);
|
nodes->append(node);
|
||||||
node = node->getPreviousSibling();
|
node = node->getPreviousSibling();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SELF_AXIS :
|
case SELF_AXIS :
|
||||||
if (nodeExpr->matches(context, context, cs))
|
if (mNodeTest->matches(node, aContext))
|
||||||
nodes->append(context);
|
nodes->append(node);
|
||||||
break;
|
break;
|
||||||
default: //-- Children Axis
|
default: //-- Children Axis
|
||||||
{
|
{
|
||||||
Node* tmpNode = context->getFirstChild();
|
node = node->getFirstChild();
|
||||||
while (tmpNode) {
|
while (node) {
|
||||||
if (nodeExpr->matches(tmpNode, context, cs))
|
if (mNodeTest->matches(node, aContext))
|
||||||
nodes->append(tmpNode);
|
nodes->append(node);
|
||||||
tmpNode = tmpNode->getNextSibling();
|
node = node->getNextSibling();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} //-- switch
|
} //-- switch
|
||||||
|
|
||||||
//-- apply predicates
|
//-- apply predicates
|
||||||
evaluatePredicates(nodes, cs);
|
if (!isEmpty())
|
||||||
|
evaluatePredicates(nodes, aContext);
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
nodes->reverse();
|
nodes->reverse();
|
||||||
|
|
||||||
return nodes;
|
return nodes;
|
||||||
} //-- evaluate
|
}
|
||||||
|
|
||||||
/**
|
void LocationStep::fromDescendants(Node* node, txIMatchContext* cs,
|
||||||
* Returns the default priority of this Pattern based on the given Node,
|
NodeSet* nodes)
|
||||||
* context Node, and ContextState.
|
{
|
||||||
**/
|
if (!node)
|
||||||
double LocationStep::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
return;
|
||||||
if (isEmpty())
|
|
||||||
return nodeExpr->getDefaultPriority(node, context, cs);
|
|
||||||
return 0.5;
|
|
||||||
} //-- getDefaultPriority
|
|
||||||
|
|
||||||
|
Node* child = node->getFirstChild();
|
||||||
void LocationStep::fromDescendants(Node* context, ContextState* cs, NodeSet* nodes) {
|
|
||||||
|
|
||||||
if ( !context || !nodeExpr ) return;
|
|
||||||
|
|
||||||
Node* child = context->getFirstChild();
|
|
||||||
while (child) {
|
while (child) {
|
||||||
if (nodeExpr->matches(child, context, cs))
|
if (mNodeTest->matches(child, cs))
|
||||||
nodes->append(child);
|
nodes->append(child);
|
||||||
//-- check childs descendants
|
//-- check childs descendants
|
||||||
if (child->hasChildNodes())
|
if (child->hasChildNodes())
|
||||||
|
@ -227,17 +223,19 @@ void LocationStep::fromDescendants(Node* context, ContextState* cs, NodeSet* nod
|
||||||
|
|
||||||
} //-- fromDescendants
|
} //-- 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 = node->getLastChild();
|
||||||
|
|
||||||
Node* child = context->getLastChild();
|
|
||||||
while (child) {
|
while (child) {
|
||||||
//-- check childs descendants
|
//-- check childs descendants
|
||||||
if (child->hasChildNodes())
|
if (child->hasChildNodes())
|
||||||
fromDescendantsRev(child, cs, nodes);
|
fromDescendantsRev(child, cs, nodes);
|
||||||
|
|
||||||
if (nodeExpr->matches(child, context, cs))
|
if (mNodeTest->matches(child, cs))
|
||||||
nodes->append(child);
|
nodes->append(child);
|
||||||
|
|
||||||
child = child->getPreviousSibling();
|
child = child->getPreviousSibling();
|
||||||
|
@ -245,40 +243,13 @@ void LocationStep::fromDescendantsRev(Node* context, ContextState* cs, NodeSet*
|
||||||
|
|
||||||
} //-- fromDescendantsRev
|
} //-- 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
|
* Creates a String representation of this Expr
|
||||||
* @param str the destination String to append to
|
* @param str the destination String to append to
|
||||||
* @see Expr
|
* @see Expr
|
||||||
**/
|
**/
|
||||||
void LocationStep::toString(String& str) {
|
void LocationStep::toString(String& str) {
|
||||||
switch (axisIdentifier) {
|
switch (mAxisIdentifier) {
|
||||||
case ANCESTOR_AXIS :
|
case ANCESTOR_AXIS :
|
||||||
str.append("ancestor::");
|
str.append("ancestor::");
|
||||||
break;
|
break;
|
||||||
|
@ -318,8 +289,9 @@ void LocationStep::toString(String& str) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( nodeExpr ) nodeExpr->toString(str);
|
NS_ASSERTION(mNodeTest, "mNodeTest is null, that's verboten");
|
||||||
else str.append("null");
|
mNodeTest->toString(str);
|
||||||
PredicateList::toString(str);
|
|
||||||
} //-- toString
|
PredicateList::toString(str);
|
||||||
|
} // toString
|
||||||
|
|
||||||
|
|
|
@ -59,21 +59,20 @@ MultiplicativeExpr::~MultiplicativeExpr() {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* MultiplicativeExpr::evaluate(Node* context, ContextState* cs) {
|
ExprResult* MultiplicativeExpr::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
|
|
||||||
double rightDbl = Double::NaN;
|
double rightDbl = Double::NaN;
|
||||||
ExprResult* exprRes = 0;
|
ExprResult* exprRes = 0;
|
||||||
|
|
||||||
if ( rightExpr ) {
|
if ( rightExpr ) {
|
||||||
exprRes = rightExpr->evaluate(context, cs);
|
exprRes = rightExpr->evaluate(aContext);
|
||||||
if ( exprRes ) rightDbl = exprRes->numberValue();
|
if ( exprRes ) rightDbl = exprRes->numberValue();
|
||||||
delete exprRes;
|
delete exprRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
double leftDbl = Double::NaN;
|
double leftDbl = Double::NaN;
|
||||||
if ( leftExpr ) {
|
if ( leftExpr ) {
|
||||||
exprRes = leftExpr->evaluate(context, cs);
|
exprRes = leftExpr->evaluate(aContext);
|
||||||
if ( exprRes ) leftDbl = exprRes->numberValue();
|
if ( exprRes ) leftDbl = exprRes->numberValue();
|
||||||
delete exprRes;
|
delete exprRes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
@ -36,6 +36,7 @@
|
||||||
#include "XMLDOMUtils.h"
|
#include "XMLDOMUtils.h"
|
||||||
#include "Tokenizer.h"
|
#include "Tokenizer.h"
|
||||||
#include "txAtom.h"
|
#include "txAtom.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates a NodeSetFunctionCall of the given type
|
* Creates a NodeSetFunctionCall of the given type
|
||||||
|
@ -75,16 +76,16 @@ NodeSetFunctionCall::NodeSetFunctionCall(NodeSetFunctions aType)
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
*/
|
*/
|
||||||
ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
ExprResult* NodeSetFunctionCall::evaluate(txIEvalContext* aContext) {
|
||||||
ListIterator iter(¶ms);
|
ListIterator iter(¶ms);
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case COUNT:
|
case COUNT:
|
||||||
{
|
{
|
||||||
if (!requireParams(1, 1, aCs))
|
if (!requireParams(1, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
NodeSet* nodes;
|
NodeSet* nodes;
|
||||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext);
|
||||||
if (!nodes)
|
if (!nodes)
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
|
@ -94,11 +95,11 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||||
}
|
}
|
||||||
case ID:
|
case ID:
|
||||||
{
|
{
|
||||||
if (!requireParams(1, 1, aCs))
|
if (!requireParams(1, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
ExprResult* exprResult;
|
ExprResult* exprResult;
|
||||||
exprResult = ((Expr*)iter.next())->evaluate(aContext, aCs);
|
exprResult = ((Expr*)iter.next())->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
|
@ -108,11 +109,12 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Document* contextDoc;
|
Document* contextDoc = 0;
|
||||||
if (aContext->getNodeType() == Node::DOCUMENT_NODE)
|
Node* contextNode = aContext->getContextNode();
|
||||||
contextDoc = (Document*)aContext;
|
if (contextNode->getNodeType() == Node::DOCUMENT_NODE)
|
||||||
|
contextDoc = (Document*)contextNode;
|
||||||
else
|
else
|
||||||
contextDoc = aContext->getOwnerDocument();
|
contextDoc = contextNode->getOwnerDocument();
|
||||||
|
|
||||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||||
NodeSet* nodes = (NodeSet*)exprResult;
|
NodeSet* nodes = (NodeSet*)exprResult;
|
||||||
|
@ -123,7 +125,9 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||||
txTokenizer tokenizer(idList);
|
txTokenizer tokenizer(idList);
|
||||||
while (tokenizer.hasMoreTokens()) {
|
while (tokenizer.hasMoreTokens()) {
|
||||||
tokenizer.nextToken(id);
|
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);
|
txTokenizer tokenizer(idList);
|
||||||
while (tokenizer.hasMoreTokens()) {
|
while (tokenizer.hasMoreTokens()) {
|
||||||
tokenizer.nextToken(id);
|
tokenizer.nextToken(id);
|
||||||
resultSet->add(contextDoc->getElementById(id));
|
Node* idNode = contextDoc->getElementById(id);
|
||||||
|
if (idNode)
|
||||||
|
resultSet->add(idNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
|
@ -142,30 +148,23 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||||
}
|
}
|
||||||
case LAST:
|
case LAST:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 0, aCs))
|
if (!requireParams(0, 0, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
NodeSet* contextNodeSet = (NodeSet*)aCs->getNodeSetStack()->peek();
|
return new NumberResult(aContext->size());
|
||||||
if (!contextNodeSet) {
|
|
||||||
String err("Internal error");
|
|
||||||
aCs->recieveError(err);
|
|
||||||
return new StringResult("error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NumberResult(contextNodeSet->size());
|
|
||||||
}
|
}
|
||||||
case LOCAL_NAME:
|
case LOCAL_NAME:
|
||||||
case NAME:
|
case NAME:
|
||||||
case NAMESPACE_URI:
|
case NAMESPACE_URI:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 1, aCs))
|
if (!requireParams(0, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
Node* node = 0;
|
Node* node = 0;
|
||||||
// Check for optional arg
|
// Check for optional arg
|
||||||
if (iter.hasNext()) {
|
if (iter.hasNext()) {
|
||||||
NodeSet* nodes;
|
NodeSet* nodes;
|
||||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext);
|
||||||
if (!nodes)
|
if (!nodes)
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
|
@ -177,7 +176,7 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||||
delete nodes;
|
delete nodes;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node = aContext;
|
node = aContext->getContextNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
|
@ -219,21 +218,14 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||||
}
|
}
|
||||||
case POSITION:
|
case POSITION:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 0, aCs))
|
if (!requireParams(0, 0, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
NodeSet* contextNodeSet = (NodeSet*)aCs->getNodeSetStack()->peek();
|
return new NumberResult(aContext->position());
|
||||||
if (!contextNodeSet) {
|
|
||||||
String err("Internal error");
|
|
||||||
aCs->recieveError(err);
|
|
||||||
return new StringResult("error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NumberResult(contextNodeSet->indexOf(aContext) + 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String err("Internal error");
|
String err("Internal error");
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,7 @@
|
||||||
#include "FunctionLib.h"
|
#include "FunctionLib.h"
|
||||||
#include "XMLDOMUtils.h"
|
#include "XMLDOMUtils.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates a NumberFunctionCall of the given type
|
* Creates a NumberFunctionCall of the given type
|
||||||
|
@ -68,23 +69,23 @@ NumberFunctionCall::NumberFunctionCall(NumberFunctions aType) {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
*/
|
*/
|
||||||
ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
ExprResult* NumberFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
ListIterator iter(¶ms);
|
ListIterator iter(¶ms);
|
||||||
|
|
||||||
if (mType == NUMBER) {
|
if (mType == NUMBER) {
|
||||||
if (!requireParams(0, 1, aCs))
|
if (!requireParams(0, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!requireParams(1, 1, aCs))
|
if (!requireParams(1, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case CEILING:
|
case CEILING:
|
||||||
{
|
{
|
||||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||||
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
||||||
return new NumberResult(dbl);
|
return new NumberResult(dbl);
|
||||||
|
|
||||||
|
@ -95,7 +96,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case FLOOR:
|
case FLOOR:
|
||||||
{
|
{
|
||||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||||
if (Double::isNaN(dbl) ||
|
if (Double::isNaN(dbl) ||
|
||||||
Double::isInfinite(dbl) ||
|
Double::isInfinite(dbl) ||
|
||||||
(dbl == 0 && Double::isNeg(dbl)))
|
(dbl == 0 && Double::isNeg(dbl)))
|
||||||
|
@ -105,7 +106,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case ROUND:
|
case ROUND:
|
||||||
{
|
{
|
||||||
double dbl = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
double dbl = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||||
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
||||||
return new NumberResult(dbl);
|
return new NumberResult(dbl);
|
||||||
|
|
||||||
|
@ -117,7 +118,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
case SUM:
|
case SUM:
|
||||||
{
|
{
|
||||||
NodeSet* nodes;
|
NodeSet* nodes;
|
||||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext);
|
||||||
|
|
||||||
if (!nodes)
|
if (!nodes)
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
@ -137,16 +138,16 @@ ExprResult* NumberFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
{
|
{
|
||||||
if (iter.hasNext()) {
|
if (iter.hasNext()) {
|
||||||
return new NumberResult(
|
return new NumberResult(
|
||||||
evaluateToNumber((Expr*)iter.next(), aContext, aCs));
|
evaluateToNumber((Expr*)iter.next(), aContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
String resultStr;
|
String resultStr;
|
||||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
XMLDOMUtils::getNodeValue(aContext->getContextNode(), resultStr);
|
||||||
return new NumberResult(Double::toDouble(resultStr));
|
return new NumberResult(Double::toDouble(resultStr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String err("Internal error");
|
String err("Internal error");
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,11 +33,17 @@
|
||||||
|
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
#include "XMLUtils.h"
|
#include "XMLUtils.h"
|
||||||
|
#include "txNodeSetContext.h"
|
||||||
|
#include "txSingleNodeContext.h"
|
||||||
|
|
||||||
//------------/
|
//------------/
|
||||||
//- PathExpr -/
|
//- 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
|
* Creates a new PathExpr
|
||||||
|
@ -94,12 +100,14 @@ void PathExpr::addExpr(Expr* expr, PathOperator pathOp)
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the 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");
|
return new StringResult("error");
|
||||||
|
}
|
||||||
|
|
||||||
NodeSet* nodes = new NodeSet(context);
|
NodeSet* nodes = new NodeSet(aContext->getContextNode());
|
||||||
if (!nodes) {
|
if (!nodes) {
|
||||||
// XXX ErrorReport: out of memory
|
// XXX ErrorReport: out of memory
|
||||||
NS_ASSERTION(0, "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())) {
|
while ((pxi = (PathExprItem*)iter.next())) {
|
||||||
NodeSet* tmpNodes = 0;
|
NodeSet* tmpNodes = 0;
|
||||||
for (int i = 0; i < nodes->size(); i++) {
|
txNodeSetContext eContext(nodes, aContext);
|
||||||
Node* node = nodes->get(i);
|
while (eContext.hasNext()) {
|
||||||
|
eContext.next();
|
||||||
|
Node* node = eContext.getContextNode();
|
||||||
|
|
||||||
NodeSet* resNodes;
|
NodeSet* resNodes;
|
||||||
if (pxi->pathOp == DESCENDANT_OP) {
|
if (pxi->pathOp == DESCENDANT_OP) {
|
||||||
resNodes = new NodeSet;
|
resNodes = new NodeSet;
|
||||||
evalDescendants(pxi->expr, node, cs, resNodes);
|
evalDescendants(pxi->expr, node, &eContext, resNodes);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ExprResult *res = pxi->expr->evaluate(node, cs);
|
ExprResult *res = pxi->expr->evaluate(&eContext);
|
||||||
if (!res || (res->getResultType() != ExprResult::NODESET)) {
|
if (!res || (res->getResultType() != ExprResult::NODESET)) {
|
||||||
//XXX ErrorReport: report nonnodeset error
|
//XXX ErrorReport: report nonnodeset error
|
||||||
delete res;
|
delete res;
|
||||||
|
@ -147,12 +157,13 @@ ExprResult* PathExpr::evaluate(Node* context, ContextState* cs)
|
||||||
/**
|
/**
|
||||||
* Selects from the descendants of the context node
|
* Selects from the descendants of the context node
|
||||||
* all nodes that match the Expr
|
* all nodes that match the Expr
|
||||||
* -- this will be moving to a Utility class
|
|
||||||
**/
|
**/
|
||||||
void PathExpr::evalDescendants (Expr* expr, Node* context,
|
void PathExpr::evalDescendants (Expr* aStep, Node* aNode,
|
||||||
ContextState* cs, NodeSet* resNodes)
|
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)) {
|
if (!res || (res->getResultType() != ExprResult::NODESET)) {
|
||||||
//XXX ErrorReport: report nonnodeset error
|
//XXX ErrorReport: report nonnodeset error
|
||||||
}
|
}
|
||||||
|
@ -161,107 +172,19 @@ void PathExpr::evalDescendants (Expr* expr, Node* context,
|
||||||
}
|
}
|
||||||
delete res;
|
delete res;
|
||||||
|
|
||||||
MBool filterWS = cs->isStripSpaceAllowed(context);
|
MBool filterWS = aContext->isStripSpaceAllowed(aNode);
|
||||||
|
|
||||||
Node* child = context->getFirstChild();
|
Node* child = aNode->getFirstChild();
|
||||||
while (child) {
|
while (child) {
|
||||||
if (!(filterWS &&
|
if (!(filterWS &&
|
||||||
(child->getNodeType() == Node::TEXT_NODE ||
|
(child->getNodeType() == Node::TEXT_NODE ||
|
||||||
child->getNodeType() == Node::CDATA_SECTION_NODE) &&
|
child->getNodeType() == Node::CDATA_SECTION_NODE) &&
|
||||||
XMLUtils::shouldStripTextnode(child->getNodeValue())))
|
XMLUtils::shouldStripTextnode(child->getNodeValue())))
|
||||||
evalDescendants(expr, child, cs, resNodes);
|
evalDescendants(aStep, child, aContext, resNodes);
|
||||||
child = child->getNextSibling();
|
child = child->getNextSibling();
|
||||||
}
|
}
|
||||||
} //-- evalDescendants
|
} //-- 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.
|
* Returns the String representation of this Expr.
|
||||||
* @param dest the String to use when creating the String
|
* @param dest the String to use when creating the String
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
|
#include "txNodeSetContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Represents an ordered list of Predicates,
|
* Represents an ordered list of Predicates,
|
||||||
|
@ -56,38 +57,39 @@ void PredicateList::add(Expr* expr)
|
||||||
predicates.add(expr);
|
predicates.add(expr);
|
||||||
} // add
|
} // add
|
||||||
|
|
||||||
void PredicateList::evaluatePredicates(NodeSet* nodes, ContextState* cs)
|
void PredicateList::evaluatePredicates(NodeSet* nodes,
|
||||||
|
txIMatchContext* aContext)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(nodes, "called evaluatePredicates with NULL NodeSet");
|
NS_ASSERTION(nodes, "called evaluatePredicates with NULL NodeSet");
|
||||||
if (!nodes)
|
if (!nodes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cs->getNodeSetStack()->push(nodes);
|
|
||||||
NodeSet newNodes;
|
NodeSet newNodes;
|
||||||
txListIterator iter(&predicates);
|
txListIterator iter(&predicates);
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext() && !nodes->isEmpty()) {
|
||||||
Expr* expr = (Expr*)iter.next();
|
Expr* expr = (Expr*)iter.next();
|
||||||
|
txNodeSetContext predContext(nodes, aContext);
|
||||||
/*
|
/*
|
||||||
* add nodes to newNodes that match the expression
|
* add nodes to newNodes that match the expression
|
||||||
* or, if the result is a number, add the node with the right
|
* or, if the result is a number, add the node with the right
|
||||||
* position
|
* position
|
||||||
*/
|
*/
|
||||||
newNodes.clear();
|
newNodes.clear();
|
||||||
int nIdx;
|
while (predContext.hasNext()) {
|
||||||
for (nIdx = 0; nIdx < nodes->size(); nIdx++) {
|
predContext.next();
|
||||||
Node* node = nodes->get(nIdx);
|
ExprResult* exprResult = expr->evaluate(&predContext);
|
||||||
ExprResult* exprResult = expr->evaluate(node, cs);
|
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
break;
|
break;
|
||||||
switch(exprResult->getResultType()) {
|
switch(exprResult->getResultType()) {
|
||||||
case ExprResult::NUMBER :
|
case ExprResult::NUMBER :
|
||||||
// handle default, [position() == numberValue()]
|
// handle default, [position() == numberValue()]
|
||||||
if ((double)(nIdx+1) == exprResult->numberValue())
|
if ((double)predContext.position() ==
|
||||||
newNodes.append(node);
|
exprResult->numberValue())
|
||||||
|
newNodes.append(predContext.getContextNode());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (exprResult->booleanValue())
|
if (exprResult->booleanValue())
|
||||||
newNodes.append(node);
|
newNodes.append(predContext.getContextNode());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
|
@ -96,7 +98,6 @@ void PredicateList::evaluatePredicates(NodeSet* nodes, ContextState* cs)
|
||||||
nodes->clear();
|
nodes->clear();
|
||||||
nodes->append(&newNodes);
|
nodes->append(&newNodes);
|
||||||
}
|
}
|
||||||
cs->getNodeSetStack()->pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -204,16 +204,19 @@ MBool RelationalExpr::compareResults(ExprResult* left, ExprResult* right) {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* RelationalExpr::evaluate(Node* context, ContextState* cs) {
|
ExprResult* RelationalExpr::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
//-- get result of left expression
|
//-- get result of left expression
|
||||||
ExprResult* lResult = 0;
|
ExprResult* lResult = 0;
|
||||||
if ( leftExpr ) lResult = leftExpr->evaluate(context, cs);
|
if (leftExpr)
|
||||||
else return new BooleanResult();
|
lResult = leftExpr->evaluate(aContext);
|
||||||
|
else
|
||||||
|
return new BooleanResult();
|
||||||
|
|
||||||
//-- get result of right expr
|
//-- get result of right expr
|
||||||
ExprResult* rResult = 0;
|
ExprResult* rResult = 0;
|
||||||
if ( rightExpr ) rResult = rightExpr->evaluate(context, cs);
|
if (rightExpr)
|
||||||
|
rResult = rightExpr->evaluate(aContext);
|
||||||
else {
|
else {
|
||||||
delete lResult;
|
delete lResult;
|
||||||
return new BooleanResult();
|
return new BooleanResult();
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new RootExpr
|
* Creates a new RootExpr
|
||||||
|
@ -40,32 +41,19 @@ RootExpr::RootExpr(MBool aSerialize) {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* RootExpr::evaluate(Node* context, ContextState* cs)
|
ExprResult* RootExpr::evaluate(txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
if (!context)
|
Node* context;
|
||||||
return new StringResult("error");
|
if (!aContext || !(context = aContext->getContextNode())) {
|
||||||
|
NS_ASSERTION(0, "internal error");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (context->getNodeType() != Node::DOCUMENT_NODE)
|
if (context->getNodeType() != Node::DOCUMENT_NODE)
|
||||||
return new NodeSet(context->getOwnerDocument());
|
return new NodeSet(context->getOwnerDocument());
|
||||||
return new NodeSet(context);
|
return new NodeSet(context);
|
||||||
} //-- evaluate
|
} //-- 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.
|
* Returns the String representation of this Expr.
|
||||||
* @param dest the String to use when creating the String
|
* @param dest the String to use when creating the String
|
||||||
|
|
|
@ -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
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include "FunctionLib.h"
|
#include "FunctionLib.h"
|
||||||
#include "XMLDOMUtils.h"
|
#include "XMLDOMUtils.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,41 +77,42 @@ StringFunctionCall::StringFunctionCall(StringFunctions aType) : mType(aType)
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
ExprResult* StringFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
ListIterator iter(¶ms);
|
ListIterator iter(¶ms);
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case CONCAT:
|
case CONCAT:
|
||||||
{
|
{
|
||||||
if (!requireParams(2, aCs))
|
if (!requireParams(2, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String resultStr;
|
String resultStr;
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||||
}
|
}
|
||||||
return new StringResult(resultStr);
|
return new StringResult(resultStr);
|
||||||
}
|
}
|
||||||
case CONTAINS:
|
case CONTAINS:
|
||||||
{
|
{
|
||||||
if (!requireParams(2, 2, aCs))
|
if (!requireParams(2, 2, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String arg1, arg2;
|
String arg1, arg2;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||||
return new BooleanResult(arg1.indexOf(arg2) >= 0);
|
return new BooleanResult(arg1.indexOf(arg2) >= 0);
|
||||||
}
|
}
|
||||||
case NORMALIZE_SPACE:
|
case NORMALIZE_SPACE:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 1, aCs))
|
if (!requireParams(0, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String resultStr;
|
String resultStr;
|
||||||
if (iter.hasNext())
|
if (iter.hasNext())
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||||
else
|
else
|
||||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
XMLDOMUtils::getNodeValue(aContext->getContextNode(),
|
||||||
|
resultStr);
|
||||||
|
|
||||||
MBool addSpace = MB_FALSE;
|
MBool addSpace = MB_FALSE;
|
||||||
MBool first = MB_TRUE;
|
MBool first = MB_TRUE;
|
||||||
|
@ -136,35 +138,36 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case STARTS_WITH:
|
case STARTS_WITH:
|
||||||
{
|
{
|
||||||
if (!requireParams(2, 2, aCs))
|
if (!requireParams(2, 2, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String arg1, arg2;
|
String arg1, arg2;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||||
return new BooleanResult(arg1.indexOf(arg2) == 0);
|
return new BooleanResult(arg1.indexOf(arg2) == 0);
|
||||||
}
|
}
|
||||||
case STRING_LENGTH:
|
case STRING_LENGTH:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 1, aCs))
|
if (!requireParams(0, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String resultStr;
|
String resultStr;
|
||||||
if (iter.hasNext())
|
if (iter.hasNext())
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||||
else
|
else
|
||||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
XMLDOMUtils::getNodeValue(aContext->getContextNode(),
|
||||||
|
resultStr);
|
||||||
return new NumberResult(resultStr.length());
|
return new NumberResult(resultStr.length());
|
||||||
}
|
}
|
||||||
case SUBSTRING:
|
case SUBSTRING:
|
||||||
{
|
{
|
||||||
if (!requireParams(2, 3, aCs))
|
if (!requireParams(2, 3, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String src;
|
String src;
|
||||||
double start, end;
|
double start, end;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, src);
|
evaluateToString((Expr*)iter.next(), aContext, src);
|
||||||
start = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
start = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||||
|
|
||||||
// check for NaN or +/-Inf
|
// check for NaN or +/-Inf
|
||||||
if (Double::isNaN(start) ||
|
if (Double::isNaN(start) ||
|
||||||
|
@ -175,8 +178,7 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
start = floor(start + 0.5) - 1;
|
start = floor(start + 0.5) - 1;
|
||||||
if (iter.hasNext()) {
|
if (iter.hasNext()) {
|
||||||
end = start + evaluateToNumber((Expr*)iter.next(),
|
end = start + evaluateToNumber((Expr*)iter.next(),
|
||||||
aContext,
|
aContext);
|
||||||
aCs);
|
|
||||||
if (Double::isNaN(end) || end < 0)
|
if (Double::isNaN(end) || end < 0)
|
||||||
return new StringResult();
|
return new StringResult();
|
||||||
|
|
||||||
|
@ -201,12 +203,12 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case SUBSTRING_AFTER:
|
case SUBSTRING_AFTER:
|
||||||
{
|
{
|
||||||
if (!requireParams(2, 2, aCs))
|
if (!requireParams(2, 2, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String arg1, arg2;
|
String arg1, arg2;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||||
PRInt32 idx = arg1.indexOf(arg2);
|
PRInt32 idx = arg1.indexOf(arg2);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
PRInt32 len = arg2.length();
|
PRInt32 len = arg2.length();
|
||||||
|
@ -217,12 +219,12 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case SUBSTRING_BEFORE:
|
case SUBSTRING_BEFORE:
|
||||||
{
|
{
|
||||||
if (!requireParams(2, 2, aCs))
|
if (!requireParams(2, 2, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String arg1, arg2;
|
String arg1, arg2;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg1);
|
evaluateToString((Expr*)iter.next(), aContext, arg1);
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, arg2);
|
evaluateToString((Expr*)iter.next(), aContext, arg2);
|
||||||
PRInt32 idx = arg1.indexOf(arg2);
|
PRInt32 idx = arg1.indexOf(arg2);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
arg2.clear();
|
arg2.clear();
|
||||||
|
@ -233,17 +235,17 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case TRANSLATE:
|
case TRANSLATE:
|
||||||
{
|
{
|
||||||
if (!requireParams(3, 3, aCs))
|
if (!requireParams(3, 3, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String src;
|
String src;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, src);
|
evaluateToString((Expr*)iter.next(), aContext, src);
|
||||||
if (src.isEmpty())
|
if (src.isEmpty())
|
||||||
return new StringResult();
|
return new StringResult();
|
||||||
|
|
||||||
String oldChars, newChars, dest;
|
String oldChars, newChars, dest;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, oldChars);
|
evaluateToString((Expr*)iter.next(), aContext, oldChars);
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, newChars);
|
evaluateToString((Expr*)iter.next(), aContext, newChars);
|
||||||
PRInt32 i;
|
PRInt32 i;
|
||||||
for (i = 0; i < src.length(); i++) {
|
for (i = 0; i < src.length(); i++) {
|
||||||
PRInt32 idx = oldChars.indexOf(src.charAt(i));
|
PRInt32 idx = oldChars.indexOf(src.charAt(i));
|
||||||
|
@ -259,19 +261,20 @@ ExprResult* StringFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
}
|
}
|
||||||
case STRING:
|
case STRING:
|
||||||
{
|
{
|
||||||
if (!requireParams(0, 1, aCs))
|
if (!requireParams(0, 1, aContext))
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
|
|
||||||
String resultStr;
|
String resultStr;
|
||||||
if (iter.hasNext())
|
if (iter.hasNext())
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, resultStr);
|
evaluateToString((Expr*)iter.next(), aContext, resultStr);
|
||||||
else
|
else
|
||||||
XMLDOMUtils::getNodeValue(aContext, resultStr);
|
XMLDOMUtils::getNodeValue(aContext->getContextNode(),
|
||||||
|
resultStr);
|
||||||
return new StringResult(resultStr);
|
return new StringResult(resultStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String err("Internal error");
|
String err("Internal error");
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_UNEXPECTED);
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,9 @@ UnaryExpr::~UnaryExpr()
|
||||||
* for evaluation.
|
* for evaluation.
|
||||||
* @return the result of the 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();
|
double value = exprRes->numberValue();
|
||||||
delete exprRes;
|
delete exprRes;
|
||||||
#ifdef HPUX
|
#ifdef HPUX
|
||||||
|
|
|
@ -69,21 +69,22 @@ void UnionExpr::addExpr(Expr* expr) {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* UnionExpr::evaluate(Node* context, ContextState* cs)
|
ExprResult* UnionExpr::evaluate(txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
NodeSet* nodes = new NodeSet();
|
NodeSet* nodes = new NodeSet();
|
||||||
|
|
||||||
if (!context || expressions.getLength() == 0 || !nodes)
|
if (!aContext || (expressions.getLength() == 0) || !nodes)
|
||||||
return nodes;
|
return nodes;
|
||||||
|
|
||||||
txListIterator iter(&expressions);
|
txListIterator iter(&expressions);
|
||||||
|
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
Expr* expr = (Expr*)iter.next();
|
Expr* expr = (Expr*)iter.next();
|
||||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
ExprResult* exprResult = expr->evaluate(aContext);
|
||||||
if (!exprResult ||
|
if (!exprResult ||
|
||||||
exprResult->getResultType() != ExprResult::NODESET) {
|
exprResult->getResultType() != ExprResult::NODESET) {
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
|
delete nodes;
|
||||||
return new StringResult("error");
|
return new StringResult("error");
|
||||||
}
|
}
|
||||||
nodes->add((NodeSet*)exprResult);
|
nodes->add((NodeSet*)exprResult);
|
||||||
|
@ -93,45 +94,6 @@ ExprResult* UnionExpr::evaluate(Node* context, ContextState* cs)
|
||||||
return nodes;
|
return nodes;
|
||||||
} //-- evaluate
|
} //-- 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.
|
* Returns the String representation of this Expr.
|
||||||
* @param dest the String to use when creating the String
|
* @param dest the String to use when creating the String
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Expr.h"
|
#include "Expr.h"
|
||||||
|
#include "txAtoms.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
//-------------------/
|
//-------------------/
|
||||||
//- VariableRefExpr -/
|
//- VariableRefExpr -/
|
||||||
|
@ -32,9 +34,25 @@
|
||||||
/**
|
/**
|
||||||
* Creates a VariableRefExpr with the given variable name
|
* Creates a VariableRefExpr with the given variable name
|
||||||
**/
|
**/
|
||||||
VariableRefExpr::VariableRefExpr(const String& name) {
|
VariableRefExpr::VariableRefExpr(txAtom* aPrefix, txAtom* aLocalName,
|
||||||
this->name = name;
|
PRInt32 aNSID)
|
||||||
} //-- VariableRefExpr
|
: 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
|
* Evaluates this Expr based on the given context node and processor state
|
||||||
|
@ -43,9 +61,14 @@ VariableRefExpr::VariableRefExpr(const String& name) {
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
**/
|
**/
|
||||||
ExprResult* VariableRefExpr::evaluate(Node* context, ContextState* cs) {
|
ExprResult* VariableRefExpr::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
ExprResult* exprResult = cs->getVariable(name);
|
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
|
//-- make copy to prevent deletetion
|
||||||
//-- I know, I should add a #copy method to ExprResult, I will
|
//-- I know, I should add a #copy method to ExprResult, I will
|
||||||
ExprResult* copyOfResult = 0;
|
ExprResult* copyOfResult = 0;
|
||||||
|
@ -88,7 +111,16 @@ ExprResult* VariableRefExpr::evaluate(Node* context, ContextState* cs) {
|
||||||
* other #toString() methods for Expressions.
|
* other #toString() methods for Expressions.
|
||||||
* @return the String representation of this Expr.
|
* @return the String representation of this Expr.
|
||||||
**/
|
**/
|
||||||
void VariableRefExpr::toString(String& str) {
|
void VariableRefExpr::toString(String& aDest)
|
||||||
str.append('$');
|
{
|
||||||
str.append(name);
|
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
|
} //-- toString
|
||||||
|
|
|
@ -54,6 +54,8 @@ CPPSRCS = Names.cpp \
|
||||||
txRtfHandler.cpp \
|
txRtfHandler.cpp \
|
||||||
txTextHandler.cpp \
|
txTextHandler.cpp \
|
||||||
VariableBinding.cpp \
|
VariableBinding.cpp \
|
||||||
|
txXSLTPatterns.cpp \
|
||||||
|
txPatternParser.cpp \
|
||||||
XSLTProcessor.cpp
|
XSLTProcessor.cpp
|
||||||
|
|
||||||
ifdef TX_EXE
|
ifdef TX_EXE
|
||||||
|
|
|
@ -8,22 +8,19 @@
|
||||||
/**
|
/**
|
||||||
* Creates a new current function call
|
* Creates a new current function call
|
||||||
**/
|
**/
|
||||||
CurrentFunctionCall::CurrentFunctionCall(ProcessorState* ps) :
|
CurrentFunctionCall::CurrentFunctionCall(ProcessorState* aPs)
|
||||||
FunctionCall(CURRENT_FN)
|
: FunctionCall(CURRENT_FN), mPs(aPs)
|
||||||
{
|
{
|
||||||
this->processorState = ps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Evaluates this Expr based on the given context node and processor state
|
* Evaluates this Expr
|
||||||
* @param context the context node for evaluation of this Expr
|
*
|
||||||
* @param cs the ContextState containing the stack information needed
|
* @return NodeSet containing the context node used for the complete
|
||||||
* for evaluation
|
* Expr or Pattern.
|
||||||
* @return the result of the evaluation
|
*/
|
||||||
* @see FunctionCall.h
|
ExprResult* CurrentFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
**/
|
|
||||||
ExprResult* CurrentFunctionCall::evaluate(Node* context, ContextState* cs)
|
|
||||||
{
|
{
|
||||||
return new NodeSet(processorState->getCurrentNode());
|
return new NodeSet(mPs->getEvalContext()->getContextNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "XSLTFunctions.h"
|
#include "XSLTFunctions.h"
|
||||||
#include "XMLDOMUtils.h"
|
#include "XMLDOMUtils.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates a new DocumentFunctionCall.
|
* 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
|
* NOTE: the implementation is incomplete since it does not make use of the
|
||||||
* second argument (base URI)
|
* second argument (base URI)
|
||||||
* @param context the context node for evaluation of this Expr
|
* @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
|
* @return the result of the evaluation
|
||||||
*/
|
*/
|
||||||
ExprResult* DocumentFunctionCall::evaluate(Node* context, ContextState* cs)
|
ExprResult* DocumentFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
{
|
{
|
||||||
NodeSet* nodeSet = new NodeSet();
|
NodeSet* nodeSet = new NodeSet();
|
||||||
|
|
||||||
// document(object, node-set?)
|
// document(object, node-set?)
|
||||||
if (requireParams(1, 2, cs)) {
|
if (requireParams(1, 2, aContext)) {
|
||||||
ListIterator* iter = params.iterator();
|
ListIterator* iter = params.iterator();
|
||||||
Expr* param1 = (Expr*) iter->next();
|
Expr* param1 = (Expr*) iter->next();
|
||||||
ExprResult* exprResult1 = param1->evaluate(context, cs);
|
ExprResult* exprResult1 = param1->evaluate(aContext);
|
||||||
String baseURI;
|
String baseURI;
|
||||||
MBool baseURISet = MB_FALSE;
|
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
|
// We have 2 arguments, get baseURI from the first node
|
||||||
// in the resulting nodeset
|
// in the resulting nodeset
|
||||||
Expr* param2 = (Expr*) iter->next();
|
Expr* param2 = (Expr*) iter->next();
|
||||||
ExprResult* exprResult2 = param2->evaluate(context, cs);
|
ExprResult* exprResult2 = param2->evaluate(aContext);
|
||||||
if (exprResult2->getResultType() != ExprResult::NODESET) {
|
if (exprResult2->getResultType() != ExprResult::NODESET) {
|
||||||
String err("node-set expected as second argument to document(): ");
|
String err("node-set expected as second argument to document(): ");
|
||||||
toString(err);
|
toString(err);
|
||||||
cs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
|
delete exprResult1;
|
||||||
delete exprResult2;
|
delete exprResult2;
|
||||||
return nodeSet;
|
return nodeSet;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "XSLTFunctions.h"
|
#include "XSLTFunctions.h"
|
||||||
#include "XMLUtils.h"
|
#include "XMLUtils.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Implementation of XSLT 1.0 extension function: element-available
|
Implementation of XSLT 1.0 extension function: element-available
|
||||||
|
@ -47,9 +48,11 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new element-available function call
|
* 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() :
|
ElementAvailableFunctionCall::ElementAvailableFunctionCall(Element* aNode) :
|
||||||
FunctionCall(ELEMENT_AVAILABLE_FN)
|
mStylesheetNode(aNode), FunctionCall(ELEMENT_AVAILABLE_FN)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,24 +64,28 @@ ElementAvailableFunctionCall::ElementAvailableFunctionCall() :
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
ExprResult* ElementAvailableFunctionCall::evaluate(Node* context, ContextState* cs) {
|
ExprResult* ElementAvailableFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
ExprResult* result = NULL;
|
ExprResult* result = NULL;
|
||||||
|
|
||||||
if ( requireParams(1,1,cs) ) {
|
if (requireParams(1, 1, aContext)) {
|
||||||
ListIterator iter(¶ms);
|
ListIterator iter(¶ms);
|
||||||
Expr* param = (Expr*) iter.next();
|
Expr* param = (Expr*) iter.next();
|
||||||
ExprResult* exprResult = param->evaluate(context, cs);
|
ExprResult* exprResult = param->evaluate(aContext);
|
||||||
if (exprResult &&
|
if (exprResult &&
|
||||||
exprResult->getResultType() == ExprResult::STRING) {
|
exprResult->getResultType() == ExprResult::STRING) {
|
||||||
String property;
|
String property;
|
||||||
exprResult->stringValue(property);
|
exprResult->stringValue(property);
|
||||||
if (XMLUtils::isValidQName(property)) {
|
if (XMLUtils::isValidQName(property)) {
|
||||||
String prefix, propertyNsURI;
|
String prefix;
|
||||||
|
PRInt32 aNSID = kNameSpaceID_None;
|
||||||
XMLUtils::getPrefix(property, prefix);
|
XMLUtils::getPrefix(property, prefix);
|
||||||
if (!prefix.isEmpty()) {
|
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;
|
String localName;
|
||||||
XMLUtils::getLocalPart(property, localName);
|
XMLUtils::getLocalPart(property, localName);
|
||||||
if ( localName.isEqual(APPLY_IMPORTS) ||
|
if ( localName.isEqual(APPLY_IMPORTS) ||
|
||||||
|
@ -119,7 +126,7 @@ ExprResult* ElementAvailableFunctionCall::evaluate(Node* context, ContextState*
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String err("Invalid argument passed to element-available(), expecting String");
|
String err("Invalid argument passed to element-available(), expecting String");
|
||||||
delete result;
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
result = new StringResult(err);
|
result = new StringResult(err);
|
||||||
}
|
}
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "XSLTFunctions.h"
|
#include "XSLTFunctions.h"
|
||||||
#include "primitives.h"
|
#include "primitives.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#ifndef TX_EXE
|
#ifndef TX_EXE
|
||||||
|
@ -70,10 +71,9 @@ txFormatNumberFunctionCall::txFormatNumberFunctionCall(ProcessorState* aPs) :
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
*/
|
*/
|
||||||
ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
ExprResult* txFormatNumberFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
ContextState* aCs)
|
|
||||||
{
|
{
|
||||||
if (!requireParams(2, 3, aCs))
|
if (!requireParams(2, 3, aContext))
|
||||||
return new StringResult();
|
return new StringResult();
|
||||||
|
|
||||||
// Get number and format
|
// Get number and format
|
||||||
|
@ -83,16 +83,16 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
||||||
String formatStr;
|
String formatStr;
|
||||||
String formatName;
|
String formatName;
|
||||||
|
|
||||||
value = evaluateToNumber((Expr*)iter.next(), aContext, aCs);
|
value = evaluateToNumber((Expr*)iter.next(), aContext);
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, formatStr);
|
evaluateToString((Expr*)iter.next(), aContext, formatStr);
|
||||||
if (iter.hasNext())
|
if (iter.hasNext())
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, formatName);
|
evaluateToString((Expr*)iter.next(), aContext, formatName);
|
||||||
|
|
||||||
txDecimalFormat* format = mPs->getDecimalFormat(formatName);
|
txDecimalFormat* format = mPs->getDecimalFormat(formatName);
|
||||||
if (!format) {
|
if (!format) {
|
||||||
String err("unknown decimal format for: ");
|
String err("unknown decimal format for: ");
|
||||||
toString(err);
|
toString(err);
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
return new StringResult(err);
|
return new StringResult(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,8 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
||||||
else {
|
else {
|
||||||
String err(INVALID_PARAM_VALUE);
|
String err(INVALID_PARAM_VALUE);
|
||||||
toString(err);
|
toString(err);
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err,
|
||||||
|
NS_ERROR_XPATH_EVAL_FAILED);
|
||||||
return new StringResult(err);
|
return new StringResult(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,7 +172,8 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
||||||
else {
|
else {
|
||||||
String err(INVALID_PARAM_VALUE);
|
String err(INVALID_PARAM_VALUE);
|
||||||
toString(err);
|
toString(err);
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err,
|
||||||
|
NS_ERROR_XPATH_EVAL_FAILED);
|
||||||
return new StringResult(err);
|
return new StringResult(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +258,8 @@ ExprResult* txFormatNumberFunctionCall::evaluate(Node* aContext,
|
||||||
groupSize == 0) {
|
groupSize == 0) {
|
||||||
String err(INVALID_PARAM_VALUE);
|
String err(INVALID_PARAM_VALUE);
|
||||||
toString(err);
|
toString(err);
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err,
|
||||||
|
NS_ERROR_XPATH_EVAL_FAILED);
|
||||||
return new StringResult(err);
|
return new StringResult(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "FunctionLib.h"
|
#include "FunctionLib.h"
|
||||||
#include "XMLUtils.h"
|
#include "XMLUtils.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Implementation of XSLT 1.0 extension function: function-available
|
Implementation of XSLT 1.0 extension function: function-available
|
||||||
|
@ -62,13 +63,14 @@ FunctionAvailableFunctionCall::FunctionAvailableFunctionCall() :
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
ExprResult* FunctionAvailableFunctionCall::evaluate(Node* context, ContextState* cs) {
|
ExprResult* FunctionAvailableFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
ExprResult* result = NULL;
|
ExprResult* result = NULL;
|
||||||
|
|
||||||
if ( requireParams(1,1,cs) ) {
|
if (requireParams(1, 1, aContext)) {
|
||||||
ListIterator iter(¶ms);
|
ListIterator iter(¶ms);
|
||||||
Expr* param = (Expr*)iter.next();
|
Expr* param = (Expr*)iter.next();
|
||||||
ExprResult* exprResult = param->evaluate(context, cs);
|
ExprResult* exprResult = param->evaluate(aContext);
|
||||||
if (exprResult &&
|
if (exprResult &&
|
||||||
exprResult->getResultType() == ExprResult::STRING) {
|
exprResult->getResultType() == ExprResult::STRING) {
|
||||||
String property;
|
String property;
|
||||||
|
@ -119,7 +121,7 @@ ExprResult* FunctionAvailableFunctionCall::evaluate(Node* context, ContextState*
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String err("Invalid argument passed to function-available, expecting String");
|
String err("Invalid argument passed to function-available, expecting String");
|
||||||
delete result;
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
result = new StringResult(err);
|
result = new StringResult(err);
|
||||||
}
|
}
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "XSLTFunctions.h"
|
#include "XSLTFunctions.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
#ifdef TX_EXE
|
#ifdef TX_EXE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#else
|
#else
|
||||||
|
@ -55,10 +56,9 @@ GenerateIdFunctionCall::GenerateIdFunctionCall()
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
ExprResult* GenerateIdFunctionCall::evaluate(Node* aContext,
|
ExprResult* GenerateIdFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
ContextState* aCs) {
|
{
|
||||||
|
if (!requireParams(0, 1, aContext))
|
||||||
if (!requireParams(0, 1, aCs))
|
|
||||||
return new StringResult();
|
return new StringResult();
|
||||||
|
|
||||||
Node* node = 0;
|
Node* node = 0;
|
||||||
|
@ -68,14 +68,14 @@ ExprResult* GenerateIdFunctionCall::evaluate(Node* aContext,
|
||||||
txListIterator iter(¶ms);
|
txListIterator iter(¶ms);
|
||||||
Expr* param = (Expr*)iter.next();
|
Expr* param = (Expr*)iter.next();
|
||||||
|
|
||||||
ExprResult* exprResult = param->evaluate(aContext, aCs);
|
ExprResult* exprResult = param->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (exprResult->getResultType() != ExprResult::NODESET) {
|
if (exprResult->getResultType() != ExprResult::NODESET) {
|
||||||
String err("Invalid argument passed to generate-id(), "
|
String err("Invalid argument passed to generate-id(), "
|
||||||
"expecting NodeSet");
|
"expecting NodeSet");
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
return new StringResult(err);
|
return new StringResult(err);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ ExprResult* GenerateIdFunctionCall::evaluate(Node* aContext,
|
||||||
delete exprResult;
|
delete exprResult;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
node = aContext;
|
node = aContext->getContextNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate id for selected node
|
// generate id for selected node
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "XSLTFunctions.h"
|
#include "XSLTFunctions.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
#include "XMLDOMUtils.h"
|
#include "XMLDOMUtils.h"
|
||||||
|
#include "txSingleNodeContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* txKeyFunctionCall
|
* txKeyFunctionCall
|
||||||
|
@ -44,9 +45,9 @@ txKeyFunctionCall::txKeyFunctionCall(ProcessorState* aPs) :
|
||||||
* for evaluation
|
* for evaluation
|
||||||
* @return the result of the 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");
|
return new StringResult("error");
|
||||||
|
|
||||||
NodeSet* res = new NodeSet;
|
NodeSet* res = new NodeSet;
|
||||||
|
@ -57,26 +58,27 @@ ExprResult* txKeyFunctionCall::evaluate(Node* aContext, ContextState* aCs)
|
||||||
|
|
||||||
ListIterator iter(¶ms);
|
ListIterator iter(¶ms);
|
||||||
String keyName;
|
String keyName;
|
||||||
evaluateToString((Expr*)iter.next(), aContext, aCs, keyName);
|
evaluateToString((Expr*)iter.next(), aContext, keyName);
|
||||||
Expr* param = (Expr*) iter.next();
|
Expr* param = (Expr*) iter.next();
|
||||||
|
|
||||||
txXSLKey* key = mProcessorState->getKey(keyName);
|
txXSLKey* key = mProcessorState->getKey(keyName);
|
||||||
if (!key) {
|
if (!key) {
|
||||||
String err("No key with that name in: ");
|
String err("No key with that name in: ");
|
||||||
toString(err);
|
toString(err);
|
||||||
aCs->recieveError(err);
|
aContext->receiveError(err, NS_ERROR_INVALID_ARG);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult* exprResult = param->evaluate(aContext, aCs);
|
ExprResult* exprResult = param->evaluate(aContext);
|
||||||
if (!exprResult)
|
if (!exprResult)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
Document* contextDoc;
|
Document* contextDoc;
|
||||||
if (aContext->getNodeType() == Node::DOCUMENT_NODE)
|
Node* contextNode = aContext->getContextNode();
|
||||||
contextDoc = (Document*)aContext;
|
if (contextNode->getNodeType() == Node::DOCUMENT_NODE)
|
||||||
|
contextDoc = (Document*)contextNode;
|
||||||
else
|
else
|
||||||
contextDoc = aContext->getOwnerDocument();
|
contextDoc = contextNode->getOwnerDocument();
|
||||||
|
|
||||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||||
NodeSet* nodeSet = (NodeSet*) exprResult;
|
NodeSet* nodeSet = (NodeSet*) exprResult;
|
||||||
|
@ -155,7 +157,7 @@ const NodeSet* txXSLKey::getNodes(String& aKeyValue, Document* aDoc)
|
||||||
* @param aUse use-expression
|
* @param aUse use-expression
|
||||||
* @return MB_FALSE if an error occured, MB_TRUE otherwise
|
* @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)
|
if (!aMatch || !aUse)
|
||||||
return MB_FALSE;
|
return MB_FALSE;
|
||||||
|
@ -226,13 +228,12 @@ void txXSLKey::testNode(Node* aNode, NamedMap* aMap)
|
||||||
while (iter.hasNext())
|
while (iter.hasNext())
|
||||||
{
|
{
|
||||||
Key* key=(Key*)iter.next();
|
Key* key=(Key*)iter.next();
|
||||||
if (key->matchPattern->matches(aNode, 0, mProcessorState)) {
|
if (key->matchPattern->matches(aNode, mProcessorState)) {
|
||||||
NodeSet contextNodeSet(aNode);
|
txSingleNodeContext evalContext(aNode, mProcessorState);
|
||||||
mProcessorState->getNodeSetStack()->push(&contextNodeSet);
|
txIEvalContext* prevCon =
|
||||||
mProcessorState->pushCurrentNode(aNode);
|
mProcessorState->setEvalContext(&evalContext);
|
||||||
ExprResult* exprResult = key->useExpr->evaluate(aNode, mProcessorState);
|
ExprResult* exprResult = key->useExpr->evaluate(&evalContext);
|
||||||
mProcessorState->popCurrentNode();
|
mProcessorState->setEvalContext(prevCon);
|
||||||
mProcessorState->getNodeSetStack()->pop();
|
|
||||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||||
NodeSet* res = (NodeSet*)exprResult;
|
NodeSet* res = (NodeSet*)exprResult;
|
||||||
for (int i=0; i<res->size(); i++) {
|
for (int i=0; i<res->size(); i++) {
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "ProcessorState.h"
|
#include "ProcessorState.h"
|
||||||
#include "txXPathResultComparator.h"
|
#include "txXPathResultComparator.h"
|
||||||
#include "txAtoms.h"
|
#include "txAtoms.h"
|
||||||
|
#include "txForwardContext.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sorts Nodes as specified by the W3C XSLT 1.0 Recommendation
|
* 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);
|
key->mExpr = mPs->getExpr(aSortElement, ProcessorState::SelectAttr);
|
||||||
else {
|
else {
|
||||||
if (!mDefaultExpr) {
|
if (!mDefaultExpr) {
|
||||||
String expr(".");
|
txNodeTest* test = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||||
ExprParser parser;
|
mDefaultExpr = new LocationStep(test, LocationStep::SELF_AXIS);
|
||||||
mDefaultExpr = parser.createExpr(expr);
|
|
||||||
}
|
}
|
||||||
key->mExpr = mDefaultExpr;
|
key->mExpr = mDefaultExpr;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ MBool txNodeSorter::sortNodeSet(NodeSet* aNodes)
|
||||||
}
|
}
|
||||||
iter.reset();
|
iter.reset();
|
||||||
SortableNode* compNode = (SortableNode*)iter.next();
|
SortableNode* compNode = (SortableNode*)iter.next();
|
||||||
while (compNode && (compareNodes(currNode, compNode) > 0)) {
|
while (compNode && (compareNodes(currNode, compNode, aNodes) > 0)) {
|
||||||
compNode = (SortableNode*)iter.next();
|
compNode = (SortableNode*)iter.next();
|
||||||
}
|
}
|
||||||
// ... and insert in sorted list
|
// ... and insert in sorted list
|
||||||
|
@ -211,7 +211,8 @@ MBool txNodeSorter::sortNodeSet(NodeSet* aNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||||
SortableNode* aSNode2)
|
SortableNode* aSNode2,
|
||||||
|
NodeSet* aNodes)
|
||||||
{
|
{
|
||||||
txListIterator iter(&mSortKeys);
|
txListIterator iter(&mSortKeys);
|
||||||
int i;
|
int i;
|
||||||
|
@ -221,9 +222,10 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||||
SortKey* key = (SortKey*)iter.next();
|
SortKey* key = (SortKey*)iter.next();
|
||||||
// Lazy create sort values
|
// Lazy create sort values
|
||||||
if (!aSNode1->mSortValues[i]) {
|
if (!aSNode1->mSortValues[i]) {
|
||||||
mPs->pushCurrentNode(aSNode1->mNode);
|
txForwardContext evalContext(mPs, aSNode1->mNode, aNodes);
|
||||||
ExprResult* res = key->mExpr->evaluate(aSNode1->mNode, mPs);
|
txIEvalContext* priorEC = mPs->setEvalContext(&evalContext);
|
||||||
mPs->popCurrentNode();
|
ExprResult* res = key->mExpr->evaluate(&evalContext);
|
||||||
|
mPs->setEvalContext(priorEC);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
// XXX ErrorReport
|
// XXX ErrorReport
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -236,9 +238,10 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
|
||||||
delete res;
|
delete res;
|
||||||
}
|
}
|
||||||
if (!aSNode2->mSortValues[i]) {
|
if (!aSNode2->mSortValues[i]) {
|
||||||
mPs->pushCurrentNode(aSNode2->mNode);
|
txForwardContext evalContext(mPs, aSNode2->mNode, aNodes);
|
||||||
ExprResult* res = key->mExpr->evaluate(aSNode2->mNode, mPs);
|
txIEvalContext* priorEC = mPs->setEvalContext(&evalContext);
|
||||||
mPs->popCurrentNode();
|
ExprResult* res = key->mExpr->evaluate(&evalContext);
|
||||||
|
mPs->setEvalContext(priorEC);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
// XXX ErrorReport
|
// XXX ErrorReport
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -272,7 +275,7 @@ MBool txNodeSorter::getAttrAsAVT(Element* aSortElement,
|
||||||
if (!aSortElement->getAttr(aAttrName, kNameSpaceID_None, attValue))
|
if (!aSortElement->getAttr(aAttrName, kNameSpaceID_None, attValue))
|
||||||
return MB_FALSE;
|
return MB_FALSE;
|
||||||
|
|
||||||
mPs->processAttrValueTemplate(attValue, aContext, aResult);
|
mPs->processAttrValueTemplate(attValue, aSortElement, aResult);
|
||||||
return MB_TRUE;
|
return MB_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
int compareNodes(SortableNode* sNode1,
|
int compareNodes(SortableNode* sNode1,
|
||||||
SortableNode* sNode2);
|
SortableNode* sNode2,
|
||||||
|
NodeSet* aNodes);
|
||||||
|
|
||||||
MBool getAttrAsAVT(Element* aSortElement,
|
MBool getAttrAsAVT(Element* aSortElement,
|
||||||
txAtom* aAttrName,
|
txAtom* aAttrName,
|
||||||
|
|
|
@ -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
|
|
@ -1,6 +1,7 @@
|
||||||
#include "XSLTFunctions.h"
|
#include "XSLTFunctions.h"
|
||||||
#include "XMLUtils.h"
|
#include "XMLUtils.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
|
#include "txIXPathContext.h"
|
||||||
|
|
||||||
const String XSL_VERSION_PROPERTY = "version";
|
const String XSL_VERSION_PROPERTY = "version";
|
||||||
const String XSL_VENDOR_PROPERTY = "vendor";
|
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
|
* 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() :
|
SystemPropertyFunctionCall::SystemPropertyFunctionCall(Element* aNode) :
|
||||||
FunctionCall(SYSTEM_PROPERTY_FN)
|
mStylesheetNode(aNode), FunctionCall(SYSTEM_PROPERTY_FN)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,22 +29,29 @@ SystemPropertyFunctionCall::SystemPropertyFunctionCall() :
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
ExprResult* SystemPropertyFunctionCall::evaluate(Node* context, ContextState* cs) {
|
ExprResult* SystemPropertyFunctionCall::evaluate(txIEvalContext* aContext)
|
||||||
|
{
|
||||||
ExprResult* result = NULL;
|
ExprResult* result = NULL;
|
||||||
|
|
||||||
if ( requireParams(1,1,cs) ) {
|
if (requireParams(1, 1, aContext)) {
|
||||||
ListIterator* iter = params.iterator();
|
ListIterator* iter = params.iterator();
|
||||||
Expr* param = (Expr*) iter->next();
|
Expr* param = (Expr*) iter->next();
|
||||||
delete iter;
|
delete iter;
|
||||||
ExprResult* exprResult = param->evaluate(context, cs);
|
ExprResult* exprResult = param->evaluate(aContext);
|
||||||
if (exprResult->getResultType() == ExprResult::STRING) {
|
if (exprResult->getResultType() == ExprResult::STRING) {
|
||||||
String property;
|
String property;
|
||||||
exprResult->stringValue(property);
|
exprResult->stringValue(property);
|
||||||
if (XMLUtils::isValidQName(property)) {
|
if (XMLUtils::isValidQName(property)) {
|
||||||
String propertyNsURI, prefix;
|
String prefix;
|
||||||
|
PRInt32 namespaceID = kNameSpaceID_None;
|
||||||
XMLUtils::getPrefix(property, prefix);
|
XMLUtils::getPrefix(property, prefix);
|
||||||
cs->getNameSpaceURIFromPrefix(prefix, propertyNsURI);
|
if (!prefix.isEmpty()) {
|
||||||
if (propertyNsURI.isEqual(XSLT_NS)) {
|
txAtom* prefixAtom = TX_GET_ATOM(prefix);
|
||||||
|
namespaceID =
|
||||||
|
mStylesheetNode->lookupNamespaceID(prefixAtom);
|
||||||
|
TX_IF_RELEASE_ATOM(prefixAtom);
|
||||||
|
}
|
||||||
|
if (namespaceID == kNameSpaceID_XSLT) {
|
||||||
String localName;
|
String localName;
|
||||||
XMLUtils::getLocalPart(property, localName);
|
XMLUtils::getLocalPart(property, localName);
|
||||||
if (localName.isEqual(XSL_VERSION_PROPERTY))
|
if (localName.isEqual(XSL_VERSION_PROPERTY))
|
||||||
|
@ -55,6 +65,7 @@ ExprResult* SystemPropertyFunctionCall::evaluate(Node* context, ContextState* cs
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
String err("Invalid argument passed to system-property(), expecting String");
|
String err("Invalid argument passed to system-property(), expecting String");
|
||||||
|
aContext->receiveError(err, NS_ERROR_XPATH_INVALID_ARG);
|
||||||
result = new StringResult(err);
|
result = new StringResult(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,14 +51,9 @@ public:
|
||||||
DocumentFunctionCall(ProcessorState* aPs, Node* aDefResolveNode);
|
DocumentFunctionCall(ProcessorState* aPs, Node* aDefResolveNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates this Expr based on the given context node and processor state
|
* Virtual methods from FunctionCall
|
||||||
* @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 ExprResult* evaluate(Node* context, ContextState* cs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProcessorState* mProcessorState;
|
ProcessorState* mProcessorState;
|
||||||
|
@ -80,12 +75,10 @@ public:
|
||||||
/*
|
/*
|
||||||
* Evaluates a key() xslt-functioncall. First argument is name of key
|
* Evaluates a key() xslt-functioncall. First argument is name of key
|
||||||
* to use, second argument is value to look up.
|
* 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
|
* Virtual function from FunctionCall
|
||||||
* for evaluation
|
|
||||||
* @return the result of the evaluation
|
|
||||||
*/
|
*/
|
||||||
virtual ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProcessorState* mProcessorState;
|
ProcessorState* mProcessorState;
|
||||||
|
@ -120,7 +113,7 @@ public:
|
||||||
* @param aUse use-expression
|
* @param aUse use-expression
|
||||||
* @return MB_FALSE if an error occured, MB_TRUE otherwise
|
* @return MB_FALSE if an error occured, MB_TRUE otherwise
|
||||||
*/
|
*/
|
||||||
MBool addKey(Pattern* aMatch, Expr* aUse);
|
MBool addKey(txPattern* aMatch, Expr* aUse);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
|
@ -150,7 +143,7 @@ private:
|
||||||
* represents one match/use pair
|
* represents one match/use pair
|
||||||
*/
|
*/
|
||||||
struct Key {
|
struct Key {
|
||||||
Pattern* matchPattern;
|
txPattern* matchPattern;
|
||||||
Expr* useExpr;
|
Expr* useExpr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -191,14 +184,9 @@ public:
|
||||||
txFormatNumberFunctionCall(ProcessorState* aPs);
|
txFormatNumberFunctionCall(ProcessorState* aPs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates this Expr based on the given context node and processor state
|
* Virtual function from FunctionCall
|
||||||
* @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 ExprResult* evaluate(Node* aContext, ContextState* aCs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const UNICODE_CHAR FORMAT_QUOTE;
|
static const UNICODE_CHAR FORMAT_QUOTE;
|
||||||
|
@ -255,17 +243,12 @@ public:
|
||||||
CurrentFunctionCall(ProcessorState* ps);
|
CurrentFunctionCall(ProcessorState* ps);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates this Expr based on the given context node and processor state
|
* Virtual function from FunctionCall
|
||||||
* @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 ExprResult* evaluate(Node* context, ContextState* cs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProcessorState* processorState;
|
ProcessorState* mPs;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -288,7 +271,7 @@ public:
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
@ -313,7 +296,7 @@ public:
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char printfFmt[];
|
static const char printfFmt[];
|
||||||
|
@ -328,8 +311,10 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new system-property() function call
|
* 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
|
* Evaluates this Expr based on the given context node and processor state
|
||||||
|
@ -339,9 +324,13 @@ public:
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*
|
||||||
|
* resolve namespaceIDs with this node
|
||||||
|
*/
|
||||||
|
Element* mStylesheetNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -353,8 +342,10 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new element-available() function call
|
* 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
|
* Evaluates this Expr based on the given context node and processor state
|
||||||
|
@ -364,9 +355,13 @@ public:
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*
|
||||||
|
* resolve namespaceIDs with this node
|
||||||
|
*/
|
||||||
|
Element* mStylesheetNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -389,7 +384,7 @@ public:
|
||||||
* @return the result of the evaluation
|
* @return the result of the evaluation
|
||||||
* @see FunctionCall.h
|
* @see FunctionCall.h
|
||||||
**/
|
**/
|
||||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
ExprResult* evaluate(txIEvalContext* aContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
Загрузка…
Ссылка в новой задаче