parameterised XPathValue and XPathValuePtr

This commit is contained in:
jez_higgins 2005-08-16 15:29:02 +00:00
parent ffffbff9ce
commit a71eb0345f
21 changed files with 533 additions and 511 deletions

View file

@ -14,8 +14,8 @@ public:
PlusOperator(XPathExpression* lhs, XPathExpression* rhs) : PlusOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return NumericValue::createValue(lhs()->evaluateAsNumber(context) + rhs()->evaluateAsNumber(context)); return NumericValue::createValue(lhs()->evaluateAsNumber(context) + rhs()->evaluateAsNumber(context));
} // evaluate } // evaluate
@ -27,8 +27,8 @@ public:
MinusOperator(XPathExpression* lhs, XPathExpression* rhs) : MinusOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return NumericValue::createValue(lhs()->evaluateAsNumber(context) - rhs()->evaluateAsNumber(context)); return NumericValue::createValue(lhs()->evaluateAsNumber(context) - rhs()->evaluateAsNumber(context));
} // evaluate } // evaluate
@ -40,8 +40,8 @@ public:
MultiplyOperator(XPathExpression* lhs, XPathExpression* rhs) : MultiplyOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return NumericValue::createValue(lhs()->evaluateAsNumber(context) * rhs()->evaluateAsNumber(context)); return NumericValue::createValue(lhs()->evaluateAsNumber(context) * rhs()->evaluateAsNumber(context));
} // evaluate } // evaluate
@ -53,8 +53,8 @@ public:
DivideOperator(XPathExpression* lhs, XPathExpression* rhs) : DivideOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return NumericValue::createValue(lhs()->evaluateAsNumber(context) / rhs()->evaluateAsNumber(context)); return NumericValue::createValue(lhs()->evaluateAsNumber(context) / rhs()->evaluateAsNumber(context));
} // evaluate } // evaluate
@ -66,8 +66,8 @@ public:
ModOperator(XPathExpression* lhs, XPathExpression* rhs) : ModOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return NumericValue::createValue(static_cast<long>(lhs()->evaluateAsNumber(context)) % static_cast<long>(rhs()->evaluateAsNumber(context))); return NumericValue::createValue(static_cast<long>(lhs()->evaluateAsNumber(context)) % static_cast<long>(rhs()->evaluateAsNumber(context)));
} // evaluate } // evaluate
@ -79,8 +79,8 @@ public:
UnaryNegative(XPathExpression* expr) : UnaryNegative(XPathExpression* expr) :
UnaryExpression(expr) { } UnaryExpression(expr) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return NumericValue::createValue(-expr()->evaluate(context, executionContext)->asNumber()); return NumericValue::createValue(-expr()->evaluate(context, executionContext)->asNumber());
} // evaluate } // evaluate

View file

@ -30,14 +30,14 @@ public:
void setPosition(unsigned int pos) { position_ = pos; } void setPosition(unsigned int pos) { position_ = pos; }
const VariableResolver& variableResolver() const { return variableResolver_.get(); } const VariableResolver<std::string>& variableResolver() const { return variableResolver_.get(); }
void setVariableResolver(const VariableResolver& resolver) { variableResolver_.set(resolver); } void setVariableResolver(const VariableResolver<std::string>& resolver) { variableResolver_.set(resolver); }
void setVariableResolver(VariableResolverPtr& resolver) { variableResolver_.set(resolver); } void setVariableResolver(VariableResolverPtr<std::string>& resolver) { variableResolver_.set(resolver); }
private: private:
size_t position_; size_t position_;
size_t last_; size_t last_;
ResolverHolder<const VariableResolver> variableResolver_; ResolverHolder<const VariableResolver<std::string> > variableResolver_;
ExecutionContext(const ExecutionContext&); ExecutionContext(const ExecutionContext&);
ExecutionContext& operator=(const ExecutionContext&); ExecutionContext& operator=(const ExecutionContext&);

View file

@ -19,7 +19,7 @@ protected:
public: public:
virtual ~XPathExpression() { } virtual ~XPathExpression() { }
XPathValuePtr evaluate(const DOM::Node<std::string>& context) const XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context) const
{ {
ExecutionContext executionContext; ExecutionContext executionContext;
return evaluate(context, executionContext); return evaluate(context, executionContext);
@ -30,8 +30,8 @@ public:
virtual std::string evaluateAsString(const DOM::Node<std::string>& context) const { return evaluate(context)->asString(); } virtual std::string evaluateAsString(const DOM::Node<std::string>& context) const { return evaluate(context)->asString(); }
virtual NodeSet<std::string> evaluateAsNodeSet(const DOM::Node<std::string>& context) const { return evaluate(context)->asNodeSet(); } virtual NodeSet<std::string> evaluateAsNodeSet(const DOM::Node<std::string>& context) const { return evaluate(context)->asNodeSet(); }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const Arabica::XPath::ExecutionContext& executionContext) const = 0; const Arabica::XPath::ExecutionContext& executionContext) const = 0;
private: private:
XPathExpression(const XPathExpression&); XPathExpression(const XPathExpression&);

View file

@ -27,8 +27,8 @@ protected:
public: public:
virtual ~XPathFunction() { } virtual ~XPathFunction() { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const = 0; const ExecutionContext& executionContext) const = 0;
protected: protected:
size_t argCount() const { return args_.size(); } size_t argCount() const { return args_.size(); }
@ -73,8 +73,8 @@ class LastFn : public XPathFunction
public: public:
LastFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { } LastFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new NumericValue(executionContext.last()); return new NumericValue(executionContext.last());
} // evaluate } // evaluate
@ -86,8 +86,8 @@ class PositionFn : public XPathFunction
public: public:
PositionFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { } PositionFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new NumericValue(executionContext.position()); return new NumericValue(executionContext.position());
} // evaluate } // evaluate
@ -99,8 +99,8 @@ class CountFn : public XPathFunction
public: public:
CountFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { } CountFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new NumericValue(argAsNodeSet(0, context, executionContext).size()); return new NumericValue(argAsNodeSet(0, context, executionContext).size());
} // evaluate } // evaluate
@ -113,8 +113,8 @@ class LocalNameFn : public XPathFunction
public: public:
LocalNameFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { } LocalNameFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
DOM::Node<std::string> node; DOM::Node<std::string> node;
if(argCount() == 0) if(argCount() == 0)
@ -146,8 +146,8 @@ class NamespaceURIFn : public XPathFunction
public: public:
NamespaceURIFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { } NamespaceURIFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
DOM::Node<std::string> node; DOM::Node<std::string> node;
if(argCount() == 0) if(argCount() == 0)
@ -178,8 +178,8 @@ class NameFn : public XPathFunction
public: public:
NameFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { } NameFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
DOM::Node<std::string> node; DOM::Node<std::string> node;
if(argCount() == 0) if(argCount() == 0)
@ -214,8 +214,8 @@ class StringFn : public XPathFunction
public: public:
StringFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { } StringFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new StringValue((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context)); return new StringValue((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context));
} // evaluate } // evaluate
@ -227,8 +227,8 @@ class ConcatFn : public XPathFunction
public: public:
ConcatFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, -1, args) { } ConcatFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, -1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
std::string s; std::string s;
for(size_t a = 0, ae = argCount(); a < ae; ++a) for(size_t a = 0, ae = argCount(); a < ae; ++a)
@ -243,8 +243,8 @@ class StartsWithFn : public XPathFunction
public: public:
StartsWithFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { } StartsWithFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
std::string value = argAsString(0, context, executionContext); std::string value = argAsString(0, context, executionContext);
std::string start = argAsString(1, context, executionContext); std::string start = argAsString(1, context, executionContext);
@ -266,8 +266,8 @@ class ContainsFn : public XPathFunction
public: public:
ContainsFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { } ContainsFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new BoolValue(argAsString(0, context, executionContext).find(argAsString(1, context, executionContext)) != std::string::npos); return new BoolValue(argAsString(0, context, executionContext).find(argAsString(1, context, executionContext)) != std::string::npos);
} // evaluate } // evaluate
@ -279,8 +279,8 @@ class SubstringBeforeFn : public XPathFunction
public: public:
SubstringBeforeFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { } SubstringBeforeFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
std::string value = argAsString(0, context, executionContext); std::string value = argAsString(0, context, executionContext);
size_t splitAt = value.find(argAsString(1, context, executionContext)); size_t splitAt = value.find(argAsString(1, context, executionContext));
@ -298,8 +298,8 @@ class SubstringAfterFn : public XPathFunction
public: public:
SubstringAfterFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { } SubstringAfterFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
std::string value = argAsString(0, context, executionContext); std::string value = argAsString(0, context, executionContext);
std::string split = argAsString(1, context, executionContext); std::string split = argAsString(1, context, executionContext);
@ -318,8 +318,8 @@ class SubstringFn : public XPathFunction
public: public:
SubstringFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 3, args) { } SubstringFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 3, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
std::string value = argAsString(0, context, executionContext); std::string value = argAsString(0, context, executionContext);
double startAt = roundNumber(argAsNumber(1, context, executionContext)) - 1; double startAt = roundNumber(argAsNumber(1, context, executionContext)) - 1;
@ -343,8 +343,8 @@ class StringLengthFn : public XPathFunction
public: public:
StringLengthFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { } StringLengthFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new NumericValue(((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context)).length()); return new NumericValue(((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context)).length());
} // evaluate } // evaluate
@ -356,8 +356,8 @@ class NormalizeSpaceFn : public XPathFunction
public: public:
NormalizeSpaceFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { } NormalizeSpaceFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
std::string value = ((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context)); std::string value = ((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context));
size_t i = 0, ie = value.length(); size_t i = 0, ie = value.length();
@ -389,8 +389,8 @@ class TranslateFn : public XPathFunction
public: public:
TranslateFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(3, 3, args) { } TranslateFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(3, 3, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
std::string str = argAsString(0, context, executionContext); std::string str = argAsString(0, context, executionContext);
std::string from = argAsString(1, context, executionContext); std::string from = argAsString(1, context, executionContext);
@ -421,8 +421,8 @@ class BooleanFn : public XPathFunction
public: public:
BooleanFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { } BooleanFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new BoolValue(argAsBool(0, context, executionContext)); return new BoolValue(argAsBool(0, context, executionContext));
} // evaluate } // evaluate
@ -434,8 +434,8 @@ class NotFn : public XPathFunction
public: public:
NotFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { } NotFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new BoolValue(!argAsBool(0, context, executionContext)); return new BoolValue(!argAsBool(0, context, executionContext));
} }
@ -447,8 +447,8 @@ class TrueFn : public XPathFunction
public: public:
TrueFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { } TrueFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new BoolValue(true); return new BoolValue(true);
} // evaluate } // evaluate
@ -460,8 +460,8 @@ class FalseFn : public XPathFunction
public: public:
FalseFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { } FalseFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new BoolValue(false); return new BoolValue(false);
} // evaluate } // evaluate
@ -478,8 +478,8 @@ class NumberFn : public XPathFunction
public: public:
NumberFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { } NumberFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
double result = (argCount() > 0) ? argAsNumber(0, context, executionContext) : double result = (argCount() > 0) ? argAsNumber(0, context, executionContext) :
StringValue(nodeStringValue(context)).asNumber(); StringValue(nodeStringValue(context)).asNumber();
@ -493,8 +493,8 @@ class SumFn : public XPathFunction
public: public:
SumFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { } SumFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
double sum = 0; double sum = 0;
NodeSet<std::string> ns = argAsNodeSet(0, context, executionContext); NodeSet<std::string> ns = argAsNodeSet(0, context, executionContext);
@ -510,8 +510,8 @@ class FloorFn : public XPathFunction
public: public:
FloorFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { } FloorFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new NumericValue(std::floor(argAsNumber(0, context, executionContext))); return new NumericValue(std::floor(argAsNumber(0, context, executionContext)));
} // evaluate } // evaluate
@ -523,8 +523,8 @@ class CeilingFn : public XPathFunction
public: public:
CeilingFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { } CeilingFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new NumericValue(std::ceil(argAsNumber(0, context, executionContext))); return new NumericValue(std::ceil(argAsNumber(0, context, executionContext)));
} // evaluate } // evaluate
@ -536,8 +536,8 @@ class RoundFn : public XPathFunction
public: public:
RoundFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { } RoundFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
virtual XPathValue* evaluate(const DOM::Node<std::string>& context, virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return new NumericValue(roundNumber(argAsNumber(0, context, executionContext))); return new NumericValue(roundNumber(argAsNumber(0, context, executionContext)));
} // evaluate } // evaluate

View file

@ -62,10 +62,10 @@ public:
delete func_; delete func_;
} // ~FunctionHolder } // ~FunctionHolder
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return XPathValuePtr(func_->evaluate(context, executionContext)); return XPathValuePtr<std::string>(func_->evaluate(context, executionContext));
} // evaluate } // evaluate
static FunctionHolder* createFunction(const std::string& name, static FunctionHolder* createFunction(const std::string& name,

View file

@ -14,8 +14,8 @@ public:
OrOperator(XPathExpression* lhs, XPathExpression* rhs) : OrOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
// From XPath 1.0 Rec, section 3.4 // From XPath 1.0 Rec, section 3.4
// An or expression is evaluated by evaluating each operand and converting its value // An or expression is evaluated by evaluating each operand and converting its value
@ -34,8 +34,8 @@ public:
AndOperator(XPathExpression* lhs, XPathExpression* rhs) : AndOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
// From XPath 1.0 Rec, section 3.4 // From XPath 1.0 Rec, section 3.4
// An and expression is evaluated by evaluating each operand and converting its value // An and expression is evaluated by evaluating each operand and converting its value

View file

@ -99,6 +99,7 @@ private:
bool sorted_; bool sorted_;
}; // NodeSet }; // NodeSet
template<class string_type>
class XPathValue class XPathValue
{ {
protected: protected:
@ -109,8 +110,8 @@ public:
virtual bool asBool() const = 0; virtual bool asBool() const = 0;
virtual double asNumber() const = 0; virtual double asNumber() const = 0;
virtual std::string asString() const = 0; virtual string_type asString() const = 0;
virtual const NodeSet<std::string>& asNodeSet() const = 0; virtual const NodeSet<string_type>& asNodeSet() const = 0;
virtual ValueType type() const = 0; virtual ValueType type() const = 0;
@ -120,10 +121,11 @@ private:
XPathValue& operator=(const XPathValue&); XPathValue& operator=(const XPathValue&);
}; // class XPathValue }; // class XPathValue
class XPathValuePtr : public boost::shared_ptr<const XPathValue> template<class string_type>
class XPathValuePtr : public boost::shared_ptr<const XPathValue<string_type> >
{ {
public: public:
explicit XPathValuePtr(const XPathValue* v) : boost::shared_ptr<const XPathValue>(v) { } explicit XPathValuePtr(const XPathValue<string_type>* v) : boost::shared_ptr<const XPathValue<string_type> >(v) { }
}; };
const double NaN = std::sqrt(-2.0); const double NaN = std::sqrt(-2.0);
@ -147,15 +149,61 @@ inline double roundNumber(double value)
return value; return value;
} // roundNumber } // roundNumber
double stringAsNumber(const std::string& str); template<class string_type>
double nodeNumberValue(const DOM::Node<std::string>& node); double stringAsNumber(const string_type& str)
std::string nodeStringValue(const DOM::Node<std::string>& node); {
try {
return boost::lexical_cast<double>(str);
} // try
catch(const boost::bad_lexical_cast&) {
return NaN;
} // catch
} // stringAsNumber
bool areEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs); template<class string_type>
bool isLessThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs); double nodeNumberValue(const DOM::Node<string_type>& node)
bool isLessThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs); {
bool isGreaterThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs); return stringAsNumber(nodeStringValue(node));
bool isGreaterThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs); } // nodeNumberValue
template<class string_type>
string_type nodeStringValue(const DOM::Node<string_type>& node)
{
switch(node.getNodeType())
{
case DOM::Node_base::DOCUMENT_NODE:
case DOM::Node_base::DOCUMENT_FRAGMENT_NODE:
case DOM::Node_base::ELEMENT_NODE:
{
std::ostringstream os;
AxisEnumerator ae(node, DESCENDANT);
while(*ae != 0)
{
if((ae->getNodeType() == DOM::Node_base::TEXT_NODE) ||
(ae->getNodeType() == DOM::Node_base::CDATA_SECTION_NODE))
os << ae->getNodeValue();
++ae;
} // while
return os.str();
} // case
case DOM::Node_base::ATTRIBUTE_NODE:
case DOM::Node_base::PROCESSING_INSTRUCTION_NODE:
case DOM::Node_base::COMMENT_NODE:
case DOM::Node_base::TEXT_NODE:
case DOM::Node_base::CDATA_SECTION_NODE:
return node.getNodeValue();
default:
throw std::runtime_error("Don't know how to calculate string-value of " + node.getNodeName());
} // switch
} // nodeStringValue
template<class string_type> bool areEqual(const XPathValuePtr<string_type>& lhs, const XPathValuePtr<string_type>& rhs);
template<class string_type> bool isLessThan(const XPathValuePtr<string_type>& lhs, const XPathValuePtr<string_type>& rhs);
template<class string_type> bool isLessThanEquals(const XPathValuePtr<string_type>& lhs, const XPathValuePtr<string_type>& rhs);
template<class string_type> bool isGreaterThan(const XPathValuePtr<string_type>& lhs, const XPathValuePtr<string_type>& rhs);
template<class string_type> bool isGreaterThanEquals(const XPathValuePtr<string_type>& lhs, const XPathValuePtr<string_type>& rhs);
} // namespace XPath } // namespace XPath
} // namespace Arabica } // namespace Arabica

View file

@ -47,18 +47,18 @@ public:
XPathExpressionPtr compile(const std::string& xpath) const; XPathExpressionPtr compile(const std::string& xpath) const;
XPathExpressionPtr compile_expr(const std::string& xpath) const; XPathExpressionPtr compile_expr(const std::string& xpath) const;
XPathValuePtr evaluate(const std::string& xpath, const DOM::Node<std::string>& context) const; XPathValuePtr<std::string> evaluate(const std::string& xpath, const DOM::Node<std::string>& context) const;
XPathValuePtr evaluate_expr(const std::string& xpath, const DOM::Node<std::string>& context) const; XPathValuePtr<std::string> evaluate_expr(const std::string& xpath, const DOM::Node<std::string>& context) const;
void setNamespaceContext(const NamespaceContext& namespaceContext) { namespaceContext_.set(namespaceContext); } void setNamespaceContext(const NamespaceContext& namespaceContext) { namespaceContext_.set(namespaceContext); }
void setNamespaceContext(NamespaceContextPtr namespaceContext) { namespaceContext_.set(namespaceContext); } void setNamespaceContext(NamespaceContextPtr namespaceContext) { namespaceContext_.set(namespaceContext); }
const NamespaceContext& getNamespaceContext() const { return namespaceContext_.get(); } const NamespaceContext& getNamespaceContext() const { return namespaceContext_.get(); }
void resetNamespaceContext() { namespaceContext_.set(NamespaceContextPtr(new NullNamespaceContext())); } void resetNamespaceContext() { namespaceContext_.set(NamespaceContextPtr(new NullNamespaceContext())); }
void setVariableResolver(const VariableResolver& variableResolver) { variableResolver_.set(variableResolver); } void setVariableResolver(const VariableResolver<std::string>& variableResolver) { variableResolver_.set(variableResolver); }
void setVariableResolver(VariableResolverPtr variableResolver) { variableResolver_.set(variableResolver); } void setVariableResolver(VariableResolverPtr<std::string> variableResolver) { variableResolver_.set(variableResolver); }
const VariableResolver& getVariableResolver() const { return variableResolver_.get(); } const VariableResolver<std::string>& getVariableResolver() const { return variableResolver_.get(); }
void resetVariableResolver() { variableResolver_.set(VariableResolverPtr(new NullVariableResolver())); } void resetVariableResolver() { variableResolver_.set(VariableResolverPtr<std::string>(new NullVariableResolver<std::string>())); }
void setFunctionResolver(const FunctionResolver& functionResolver) { functionResolver_.set(functionResolver); } void setFunctionResolver(const FunctionResolver& functionResolver) { functionResolver_.set(functionResolver); }
void setFunctionResolver(FunctionResolverPtr functionResolver) { functionResolver_.set(functionResolver); } void setFunctionResolver(FunctionResolverPtr functionResolver) { functionResolver_.set(functionResolver); }
@ -73,7 +73,7 @@ private:
xpath_grammar xpathg_; xpath_grammar xpathg_;
ResolverHolder<const NamespaceContext> namespaceContext_; ResolverHolder<const NamespaceContext> namespaceContext_;
ResolverHolder<const VariableResolver> variableResolver_; ResolverHolder<const VariableResolver<std::string> > variableResolver_;
ResolverHolder<const FunctionResolver> functionResolver_; ResolverHolder<const FunctionResolver> functionResolver_;
typedef XPathExpression* (*compileFn)(node_iter_t const& i, CompilationContext& context); typedef XPathExpression* (*compileFn)(node_iter_t const& i, CompilationContext& context);

View file

@ -14,8 +14,8 @@ public:
EqualsOperator(XPathExpression* lhs, XPathExpression* rhs) : EqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return BoolValue::createValue(areEqual(lhs()->evaluate(context, executionContext), return BoolValue::createValue(areEqual(lhs()->evaluate(context, executionContext),
rhs()->evaluate(context, executionContext))); rhs()->evaluate(context, executionContext)));
@ -28,8 +28,8 @@ public:
NotEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) : NotEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return BoolValue::createValue(!areEqual(lhs()->evaluate(context, executionContext), return BoolValue::createValue(!areEqual(lhs()->evaluate(context, executionContext),
rhs()->evaluate(context, executionContext))); rhs()->evaluate(context, executionContext)));
@ -42,8 +42,8 @@ public:
LessThanOperator(XPathExpression* lhs, XPathExpression* rhs) : LessThanOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return BoolValue::createValue(isLessThan(lhs()->evaluate(context, executionContext), return BoolValue::createValue(isLessThan(lhs()->evaluate(context, executionContext),
rhs()->evaluate(context, executionContext))); rhs()->evaluate(context, executionContext)));
@ -56,8 +56,8 @@ public:
LessThanEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) : LessThanEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return BoolValue::createValue(isLessThanEquals(lhs()->evaluate(context, executionContext), return BoolValue::createValue(isLessThanEquals(lhs()->evaluate(context, executionContext),
rhs()->evaluate(context, executionContext))); rhs()->evaluate(context, executionContext)));
@ -70,8 +70,8 @@ public:
GreaterThanOperator(XPathExpression* lhs, XPathExpression* rhs) : GreaterThanOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return BoolValue::createValue(isGreaterThan(lhs()->evaluate(context, executionContext), return BoolValue::createValue(isGreaterThan(lhs()->evaluate(context, executionContext),
rhs()->evaluate(context, executionContext))); rhs()->evaluate(context, executionContext)));
@ -84,8 +84,8 @@ public:
GreaterThanEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) : GreaterThanEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return BoolValue::createValue(isGreaterThanEquals(lhs()->evaluate(context, executionContext), return BoolValue::createValue(isGreaterThanEquals(lhs()->evaluate(context, executionContext),
rhs()->evaluate(context, executionContext))); rhs()->evaluate(context, executionContext)));

View file

@ -29,8 +29,8 @@ public:
delete *p; delete *p;
} // ~StepExpression } // ~StepExpression
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const = 0; virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const = 0;
virtual XPathValuePtr evaluate(NodeSet<std::string>& context, const ExecutionContext& executionContext) const = 0; virtual XPathValuePtr<std::string> evaluate(NodeSet<std::string>& context, const ExecutionContext& executionContext) const = 0;
bool has_predicates() const { return !predicates_.empty(); } bool has_predicates() const { return !predicates_.empty(); }
@ -52,7 +52,7 @@ private:
for(NodeSet<std::string>::iterator i = nodes.begin(); i != nodes.end(); ++i, ++position) for(NodeSet<std::string>::iterator i = nodes.begin(); i != nodes.end(); ++i, ++position)
{ {
executionContext.setPosition(position); executionContext.setPosition(position);
XPathValuePtr v = predicate->evaluate(*i, executionContext); XPathValuePtr<std::string> v = predicate->evaluate(*i, executionContext);
if((v->type() == NUMBER) && (position != v->asNumber())) if((v->type() == NUMBER) && (position != v->asNumber()))
continue; continue;
@ -89,19 +89,19 @@ public:
delete test_; delete test_;
} // StepExpression } // StepExpression
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
NodeSet<std::string> nodes; NodeSet<std::string> nodes;
enumerateOver(context, nodes, executionContext); enumerateOver(context, nodes, executionContext);
return XPathValuePtr(new NodeSetValue(nodes)); return XPathValuePtr<std::string>(new NodeSetValue(nodes));
} // evaluate } // evaluate
virtual XPathValuePtr evaluate(NodeSet<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(NodeSet<std::string>& context, const ExecutionContext& executionContext) const
{ {
NodeSet<std::string> nodes; NodeSet<std::string> nodes;
for(NodeSet<std::string>::iterator n = context.begin(); n != context.end(); ++n) for(NodeSet<std::string>::iterator n = context.begin(); n != context.end(); ++n)
enumerateOver(*n, nodes, executionContext); enumerateOver(*n, nodes, executionContext);
return XPathValuePtr(new NodeSetValue(nodes)); return XPathValuePtr<std::string>(new NodeSetValue(nodes));
} // evaluate } // evaluate
private: private:
@ -150,16 +150,16 @@ public:
delete expr_; delete expr_;
} // ExprStepExpression } // ExprStepExpression
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
if(!has_predicates()) if(!has_predicates())
return expr_->evaluate(context, executionContext); return expr_->evaluate(context, executionContext);
NodeSet<std::string> ns = expr_->evaluate(context, executionContext)->asNodeSet(); NodeSet<std::string> ns = expr_->evaluate(context, executionContext)->asNodeSet();
return XPathValuePtr(new NodeSetValue(applyPredicates(ns, executionContext))); return XPathValuePtr<std::string>(new NodeSetValue(applyPredicates(ns, executionContext)));
} // evaluate } // evaluate
virtual XPathValuePtr evaluate(NodeSet<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(NodeSet<std::string>& context, const ExecutionContext& executionContext) const
{ {
DOM::Node<std::string> c = context.top(); DOM::Node<std::string> c = context.top();
return evaluate(c, executionContext); return evaluate(c, executionContext);
@ -375,18 +375,18 @@ public:
delete *i; delete *i;
} // ~LocationPath } // ~LocationPath
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
NodeSet<std::string> nodes; NodeSet<std::string> nodes;
nodes.push_back(context); nodes.push_back(context);
for(StepList::const_iterator i = steps_.begin(); i != steps_.end(); ++i) for(StepList::const_iterator i = steps_.begin(); i != steps_.end(); ++i)
{ {
XPathValuePtr v = (*i)->evaluate(nodes, executionContext); XPathValuePtr<std::string> v = (*i)->evaluate(nodes, executionContext);
nodes = v->asNodeSet(); nodes = v->asNodeSet();
} // for ... } // for ...
return XPathValuePtr(new NodeSetValue(nodes)); return XPathValuePtr<std::string>(new NodeSetValue(nodes));
} // do_evaluate } // do_evaluate
private: private:
@ -399,7 +399,7 @@ public:
AbsoluteLocationPath(StepExpression* step) : RelativeLocationPath(step) { } AbsoluteLocationPath(StepExpression* step) : RelativeLocationPath(step) { }
AbsoluteLocationPath(const RelativeLocationPath::StepList& steps) : RelativeLocationPath(steps) { } AbsoluteLocationPath(const RelativeLocationPath::StepList& steps) : RelativeLocationPath(steps) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
int type = context.getNodeType(); int type = context.getNodeType();
if((type == DOM::Node<std::string>::DOCUMENT_NODE) || if((type == DOM::Node<std::string>::DOCUMENT_NODE) ||

View file

@ -15,13 +15,13 @@ public:
UnionExpression(XPathExpression* lhs, XPathExpression* rhs) : UnionExpression(XPathExpression* lhs, XPathExpression* rhs) :
BinaryExpression(lhs, rhs) { } BinaryExpression(lhs, rhs) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
XPathValuePtr p1 = lhs()->evaluate(context, executionContext); XPathValuePtr<std::string> p1 = lhs()->evaluate(context, executionContext);
if(p1->type() != NODE_SET) if(p1->type() != NODE_SET)
throw RuntimeException("Union operator joins node-sets. First argument is not a node-set."); throw RuntimeException("Union operator joins node-sets. First argument is not a node-set.");
XPathValuePtr p2 = rhs()->evaluate(context, executionContext); XPathValuePtr<std::string> p2 = rhs()->evaluate(context, executionContext);
if(p2->type() != NODE_SET) if(p2->type() != NODE_SET)
throw RuntimeException("Union operator joins node-sets. First argument is not a node-set."); throw RuntimeException("Union operator joins node-sets. First argument is not a node-set.");
@ -63,9 +63,9 @@ public:
} // evaluate } // evaluate
private: private:
XPathValuePtr wrap(const NodeSet<std::string>& ns) const XPathValuePtr<std::string> wrap(const NodeSet<std::string>& ns) const
{ {
return XPathValuePtr(new NodeSetValue(ns)); return XPathValuePtr<std::string>(new NodeSetValue(ns));
} // wrap } // wrap
}; // UnionExpression }; // UnionExpression

View file

@ -13,17 +13,17 @@ namespace Arabica
namespace XPath namespace XPath
{ {
class BoolValue : public XPathValue, public XPathExpression class BoolValue : public XPathValue<std::string>, public XPathExpression
{ {
public: public:
BoolValue(bool value) : BoolValue(bool value) :
value_(value) { } value_(value) { }
static XPathValuePtr createValue(bool value) { return XPathValuePtr(new BoolValue(value)); } static XPathValuePtr<std::string> createValue(bool value) { return XPathValuePtr<std::string>(new BoolValue(value)); }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
return XPathValuePtr(new BoolValue(value_)); return XPathValuePtr<std::string>(new BoolValue(value_));
} // evaluate } // evaluate
virtual bool evaluateAsBool(const DOM::Node<std::string>& context) { return asBool(); } virtual bool evaluateAsBool(const DOM::Node<std::string>& context) { return asBool(); }
virtual double evaluateAsNumber(const DOM::Node<std::string>& context) { return asNumber(); } virtual double evaluateAsNumber(const DOM::Node<std::string>& context) { return asNumber(); }
@ -41,15 +41,15 @@ private:
bool value_; bool value_;
}; // class BoolValue }; // class BoolValue
class NumericValue : public XPathValue, public XPathExpression class NumericValue : public XPathValue<std::string>, public XPathExpression
{ {
public: public:
NumericValue(double value) : NumericValue(double value) :
value_(value) { } value_(value) { }
static XPathValuePtr createValue(double value) { return XPathValuePtr(new NumericValue(value)); } static XPathValuePtr<std::string> createValue(double value) { return XPathValuePtr<std::string>(new NumericValue(value)); }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
return createValue(value_); return createValue(value_);
} // evaluate } // evaluate
@ -78,7 +78,7 @@ private:
double value_; double value_;
}; // class NumberValue }; // class NumberValue
class StringValue : public XPathValue, public XPathExpression class StringValue : public XPathValue<std::string>, public XPathExpression
{ {
public: public:
StringValue(const char* value) : StringValue(const char* value) :
@ -86,9 +86,9 @@ public:
StringValue(const std::string& value) : StringValue(const std::string& value) :
value_(value) { } value_(value) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
return XPathValuePtr(new StringValue(value_)); return XPathValuePtr<std::string>(new StringValue(value_));
} // evaluate } // evaluate
virtual bool evaluateAsBool(const DOM::Node<std::string>& context) { return asBool(); } virtual bool evaluateAsBool(const DOM::Node<std::string>& context) { return asBool(); }
virtual double evaluateAsNumber(const DOM::Node<std::string>& context) { return asNumber(); } virtual double evaluateAsNumber(const DOM::Node<std::string>& context) { return asNumber(); }
@ -109,14 +109,14 @@ private:
std::string value_; std::string value_;
}; // class StringValue }; // class StringValue
class NodeSetValue : public XPathValue, public XPathExpression class NodeSetValue : public XPathValue<std::string>, public XPathExpression
{ {
public: public:
NodeSetValue(const NodeSet<std::string>& set) : set_(set) { } NodeSetValue(const NodeSet<std::string>& set) : set_(set) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context, const ExecutionContext& executionContext) const
{ {
return XPathValuePtr(this); return XPathValuePtr<std::string>(this);
} // evaluate } // evaluate
virtual bool evaluateAsBool(const DOM::Node<std::string>& context) const{ return asBool(); } virtual bool evaluateAsBool(const DOM::Node<std::string>& context) const{ return asBool(); }
virtual double evaluateAsNumber(const DOM::Node<std::string>& context) const { return asNumber(); } virtual double evaluateAsNumber(const DOM::Node<std::string>& context) const { return asNumber(); }

View file

@ -15,8 +15,8 @@ class Variable : public XPathExpression
public: public:
Variable(const std::string& name) : name_(name) { } Variable(const std::string& name) : name_(name) { }
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context, virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
const ExecutionContext& executionContext) const const ExecutionContext& executionContext) const
{ {
return executionContext.variableResolver().resolveVariable(name_); return executionContext.variableResolver().resolveVariable(name_);
} // evaluate } // evaluate

View file

@ -15,24 +15,27 @@ public:
UnboundVariableException(const std::string& thing) : std::runtime_error("The variable '" + thing + "' is undefined.") { } UnboundVariableException(const std::string& thing) : std::runtime_error("The variable '" + thing + "' is undefined.") { }
}; // class UnboundVariableException }; // class UnboundVariableException
template<class string_type>
class VariableResolver class VariableResolver
{ {
public: public:
virtual ~VariableResolver() { } virtual ~VariableResolver() { }
virtual XPathValuePtr resolveVariable(const std::string& name) const = 0; virtual XPathValuePtr<string_type> resolveVariable(const string_type& name) const = 0;
}; // class VariableResolver }; // class VariableResolver
class VariableResolverPtr : public boost::shared_ptr<VariableResolver> template<class string_type>
class VariableResolverPtr : public boost::shared_ptr<VariableResolver<string_type> >
{ {
public: public:
explicit VariableResolverPtr(VariableResolver* vr) : boost::shared_ptr<VariableResolver>(vr) { } explicit VariableResolverPtr(VariableResolver<string_type>* vr) : boost::shared_ptr<VariableResolver<string_type> >(vr) { }
}; // class VariableResolverPtr }; // class VariableResolverPtr
class NullVariableResolver : public VariableResolver template<class string_type>
class NullVariableResolver : public VariableResolver<string_type>
{ {
public: public:
virtual XPathValuePtr resolveVariable(const std::string& name) const virtual XPathValuePtr<string_type> resolveVariable(const string_type& name) const
{ {
throw UnboundVariableException(name); throw UnboundVariableException(name);
} // resolveVariable } // resolveVariable

View file

@ -9,11 +9,89 @@ namespace Arabica
namespace XPath namespace XPath
{ {
bool nodeSetsEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs); template<class string_type>
bool nodeSetAndValueEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs); bool nodeSetsEqual(const XPathValuePtr<string_type>& lhs, const XPathValuePtr<string_type>& rhs)
{
const NodeSet<string_type>& lns = lhs->asNodeSet();
const NodeSet<string_type>& rns = rhs->asNodeSet();
double minValue(const NodeSet<std::string>& ns); if((lns.size() == 0) || (rns.size() == 0))
double maxValue(const NodeSet<std::string>& ns); return false;
std::set<string_type> values;
NodeSet<string_type>::const_iterator l = lns.begin();
string_type lvalue = nodeStringValue(*l);
for(NodeSet<string_type>::const_iterator r = rns.begin(), rend = rns.end(); r != rend; ++r)
{
string_type rvalue = nodeStringValue(*r);
if(lvalue == rvalue)
return true;
values.insert(rvalue);
} // for ...
++l;
for(NodeSet<string_type>::const_iterator lend = lns.end(); l != lend; ++l)
if(values.find(nodeStringValue(*l)) != values.end())
return true;
return false;
} // nodeSetsEqual
template<class string_type>
bool nodeSetAndValueEqual(const XPathValuePtr<string_type>& lhs, const XPathValuePtr<string_type>& rhs)
{
const NodeSet<string_type>& lns = lhs->asNodeSet();
switch(rhs->type())
{
case BOOL:
{
bool l = !lns.empty();
bool r = rhs->asBool();
return l == r;
} // case BOOL
case STRING:
return std::find_if(lns.begin(), lns.end(), compareNodeWith<std::equal_to<string_type> >(rhs->asString())) != lns.end();
case NUMBER:
return std::find_if(lns.begin(), lns.end(), compareNodeWith<std::equal_to<double> >(rhs->asNumber())) != lns.end();
default:
throw std::runtime_error("Node set == not yet implemented for type " + boost::lexical_cast<std::string>(rhs->type()));
} // switch
} // nodeSetAndValueEqual
template<class string_type>
double minValue(const NodeSet<string_type>& ns)
{
double v = nodeNumberValue(ns[0]);
for(NodeSet<string_type>::const_iterator i = ns.begin(), ie = ns.end(); i != ie; ++i)
{
double vt = nodeNumberValue(*i);
if(isNaN(vt))
continue;
if(!(vt > v)) // looks weird, but should account for infinity
v = vt;
} // for ...
return v;
} // minValue
template<class string_type>
double maxValue(const NodeSet<string_type>& ns)
{
double v = nodeNumberValue(ns[0]);
for(NodeSet<string_type>::const_iterator i = ns.begin(), ie = ns.end(); i != ie; ++i)
{
double vt = nodeNumberValue(*i);
if(isNaN(vt))
continue;
if(!(vt < v))
v = vt;
} // for ...
return v;
} // maxValue
template<class T> T nodeValue(const DOM::Node<std::string>& node); template<class T> T nodeValue(const DOM::Node<std::string>& node);
template<> std::string nodeValue(const DOM::Node<std::string>& node) { return nodeStringValue(node); } template<> std::string nodeValue(const DOM::Node<std::string>& node) { return nodeStringValue(node); }
@ -39,13 +117,13 @@ private:
}; // class compareNodeWith }; // class compareNodeWith
template<class Op> template<class Op>
bool compareNodeSets(const XPathValuePtr& lhs, const XPathValuePtr& rhs) bool compareNodeSets(const XPathValuePtr<std::string>& lhs, const XPathValuePtr<std::string>& rhs)
{ {
return Op()(minValue(lhs->asNodeSet()), maxValue(rhs->asNodeSet())); return Op()(minValue(lhs->asNodeSet()), maxValue(rhs->asNodeSet()));
} // compareNodeSets } // compareNodeSets
template<class Op> template<class Op>
bool compareNodeSetWith(const XPathValuePtr& lhs, const XPathValuePtr& rhs) bool compareNodeSetWith(const XPathValuePtr<std::string>& lhs, const XPathValuePtr<std::string>& rhs)
{ {
const NodeSet<std::string>& lns = lhs->asNodeSet(); const NodeSet<std::string>& lns = lhs->asNodeSet();
return std::find_if(lns.begin(), return std::find_if(lns.begin(),
@ -54,7 +132,7 @@ bool compareNodeSetWith(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
} // compareNodeSetAndValue } // compareNodeSetAndValue
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
bool areEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs) bool areEqual(const XPathValuePtr<std::string>& lhs, const XPathValuePtr<std::string>& rhs)
{ {
ValueType lt = lhs->type(); ValueType lt = lhs->type();
ValueType rt = rhs->type(); ValueType rt = rhs->type();
@ -79,60 +157,8 @@ bool areEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
return false; return false;
} // operator== } // operator==
bool nodeSetsEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
{
const NodeSet<std::string>& lns = lhs->asNodeSet();
const NodeSet<std::string>& rns = rhs->asNodeSet();
if((lns.size() == 0) || (rns.size() == 0))
return false;
std::set<std::string> values;
NodeSet<std::string>::const_iterator l = lns.begin();
std::string lvalue = nodeStringValue(*l);
for(NodeSet<std::string>::const_iterator r = rns.begin(), rend = rns.end(); r != rend; ++r)
{
std::string rvalue = nodeStringValue(*r);
if(lvalue == rvalue)
return true;
values.insert(rvalue);
} // for ...
++l;
for(NodeSet<std::string>::const_iterator lend = lns.end(); l != lend; ++l)
if(values.find(nodeStringValue(*l)) != values.end())
return true;
return false;
} // nodeSetsEqual
bool nodeSetAndValueEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
{
const NodeSet<std::string>& lns = lhs->asNodeSet();
switch(rhs->type())
{
case BOOL:
{
bool l = !lns.empty();
bool r = rhs->asBool();
return l == r;
} // case BOOL
case STRING:
return std::find_if(lns.begin(), lns.end(), compareNodeWith<std::equal_to<std::string> >(rhs->asString())) != lns.end();
case NUMBER:
return std::find_if(lns.begin(), lns.end(), compareNodeWith<std::equal_to<double> >(rhs->asNumber())) != lns.end();
default:
throw std::runtime_error("Node set == not yet implemented for type " + boost::lexical_cast<std::string>(rhs->type()));
} // switch
} // nodeSetAndValueEqual
/////////////////////////////// ///////////////////////////////
bool isLessThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs) bool isLessThan(const XPathValuePtr<std::string>& lhs, const XPathValuePtr<std::string>& rhs)
{ {
ValueType lt = lhs->type(); ValueType lt = lhs->type();
ValueType rt = rhs->type(); ValueType rt = rhs->type();
@ -149,7 +175,7 @@ bool isLessThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
return lhs->asNumber() < rhs->asNumber(); return lhs->asNumber() < rhs->asNumber();
} // isLessThan } // isLessThan
bool isLessThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs) bool isLessThanEquals(const XPathValuePtr<std::string>& lhs, const XPathValuePtr<std::string>& rhs)
{ {
ValueType lt = lhs->type(); ValueType lt = lhs->type();
ValueType rt = rhs->type(); ValueType rt = rhs->type();
@ -166,92 +192,17 @@ bool isLessThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
return lhs->asNumber() <= rhs->asNumber(); return lhs->asNumber() <= rhs->asNumber();
} // isLessThanEquals } // isLessThanEquals
bool isGreaterThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs) bool isGreaterThan(const XPathValuePtr<std::string>& lhs, const XPathValuePtr<std::string>& rhs)
{ {
return isLessThan(rhs, lhs); return isLessThan(rhs, lhs);
} // isGreaterThan } // isGreaterThan
bool isGreaterThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs) bool isGreaterThanEquals(const XPathValuePtr<std::string>& lhs, const XPathValuePtr<std::string>& rhs)
{ {
return isLessThanEquals(rhs, lhs); return isLessThanEquals(rhs, lhs);
} // isGreaterThanEquals } // isGreaterThanEquals
double minValue(const NodeSet<std::string>& ns)
{
double v = nodeNumberValue(ns[0]);
for(NodeSet<std::string>::const_iterator i = ns.begin(), ie = ns.end(); i != ie; ++i)
{
double vt = nodeNumberValue(*i);
if(isNaN(vt))
continue;
if(!(vt > v)) // looks weird, but should account for infinity
v = vt;
} // for ...
return v;
} // minValue
double maxValue(const NodeSet<std::string>& ns)
{
double v = nodeNumberValue(ns[0]);
for(NodeSet<std::string>::const_iterator i = ns.begin(), ie = ns.end(); i != ie; ++i)
{
double vt = nodeNumberValue(*i);
if(isNaN(vt))
continue;
if(!(vt < v))
v = vt;
} // for ...
return v;
} // maxValue
//////////////////////////////////// ////////////////////////////////////
double stringAsNumber(const std::string& str)
{
try {
return boost::lexical_cast<double>(str);
} // try
catch(const boost::bad_lexical_cast&) {
return NaN;
} // catch
} // stringAsNumber
double nodeNumberValue(const DOM::Node<std::string>& node)
{
return stringAsNumber(nodeStringValue(node));
} // nodeNumberValue
std::string nodeStringValue(const DOM::Node<std::string>& node)
{
switch(node.getNodeType())
{
case DOM::Node<std::string>::DOCUMENT_NODE:
case DOM::Node<std::string>::DOCUMENT_FRAGMENT_NODE:
case DOM::Node<std::string>::ELEMENT_NODE:
{
std::ostringstream os;
AxisEnumerator ae(node, DESCENDANT);
while(*ae != 0)
{
if((ae->getNodeType() == DOM::Node<std::string>::TEXT_NODE) ||
(ae->getNodeType() == DOM::Node<std::string>::CDATA_SECTION_NODE))
os << ae->getNodeValue();
++ae;
} // while
return os.str();
} // case
case DOM::Node<std::string>::ATTRIBUTE_NODE:
case DOM::Node<std::string>::PROCESSING_INSTRUCTION_NODE:
case DOM::Node<std::string>::COMMENT_NODE:
case DOM::Node<std::string>::TEXT_NODE:
case DOM::Node<std::string>::CDATA_SECTION_NODE:
return node.getNodeValue();
default:
throw std::runtime_error("Don't know how to calculate string-value of " + node.getNodeName());
} // switch
} // nodeStringValue
DOM::Node<std::string> node_parent_or_owner(const DOM::Node<std::string>& node) DOM::Node<std::string> node_parent_or_owner(const DOM::Node<std::string>& node)
{ {
if(node.getNodeType() == DOM::Node<std::string>::ATTRIBUTE_NODE) if(node.getNodeType() == DOM::Node<std::string>::ATTRIBUTE_NODE)

View file

@ -286,7 +286,7 @@ tree_info_t XPath::parse_xpath_expr(const std::string& str) const
return ast_parse(first, last, xpathg); return ast_parse(first, last, xpathg);
} // parse_xpath_expr } // parse_xpath_expr
XPathValuePtr XPath::evaluate(const std::string& xpath, const DOM::Node<std::string>& context) const XPathValuePtr<std::string> XPath::evaluate(const std::string& xpath, const DOM::Node<std::string>& context) const
{ {
ExecutionContext executionContext; ExecutionContext executionContext;
executionContext.setVariableResolver(getVariableResolver()); executionContext.setVariableResolver(getVariableResolver());
@ -294,7 +294,7 @@ XPathValuePtr XPath::evaluate(const std::string& xpath, const DOM::Node<std::str
return compile(xpath)->evaluate(context, executionContext); return compile(xpath)->evaluate(context, executionContext);
} // evaluate } // evaluate
XPathValuePtr XPath::evaluate_expr(const std::string& xpath, const DOM::Node<std::string>& context) const XPathValuePtr<std::string> XPath::evaluate_expr(const std::string& xpath, const DOM::Node<std::string>& context) const
{ {
ExecutionContext executionContext; ExecutionContext executionContext;
executionContext.setVariableResolver(getVariableResolver()); executionContext.setVariableResolver(getVariableResolver());

View file

@ -43,7 +43,7 @@ bool imbueInput(int& argn, int argc, const char* argv[]);
bool imbueOutput(int& argn, int argc, const char* argv[]); bool imbueOutput(int& argn, int argc, const char* argv[]);
int main(int argc, const char* argv[]) /*int main(int argc, const char* argv[])
{ {
if(!processArgs(argc, argv)) if(!processArgs(argc, argv))
{ {
@ -63,6 +63,26 @@ int main(int argc, const char* argv[])
return 0; return 0;
} // main } // main
*/
int main()
{
/* typedef oconvert_adaptor<wchar_t, std::char_traits<wchar_t>, char, std::char_traits<char> > Narrower;
Narrower oCharAdaptor(std::cout);
oCharAdaptor.imbue(std::locale(oCharAdaptor.getloc(), new utf8ucs2codecvt()));
oCharAdaptor << L"Hello Ì Õ";
oCharAdaptor.flush();*/
oconvert_adaptor<char> oByteConvertor(std::cout);
typedef oconvert_adaptor<wchar_t,
std::char_traits<wchar_t>,
char, std::char_traits<char> > Narrower;
Narrower oCharAdaptor(oByteConvertor);
oCharAdaptor.imbue(std::locale(oCharAdaptor.getloc(), new utf8ucs2codecvt()));
oCharAdaptor << L"Hello Ì Õ";
oByteConvertor.flush();
} // main
void wchar_transcode() void wchar_transcode()
{ {

View file

@ -45,7 +45,7 @@ int main(int argc, char* argv[])
if(!eh.errorsReported()) if(!eh.errorsReported())
{ {
DOM::Document<std::string> doc = domParser.getDocument(); DOM::Document<std::string> doc = domParser.getDocument();
Arabica::XPath::XPathValuePtr result = xpath->evaluate(doc); Arabica::XPath::XPathValuePtr<std::string> result = xpath->evaluate(doc);
if(result->asBool()) if(result->asBool())
std::cout << file << std::endl; std::cout << file << std::endl;
} }

File diff suppressed because it is too large Load diff

View file

@ -57,7 +57,7 @@ public:
{ {
XPathExpressionPtr step(new TestStepExpression(CHILD, new AnyNodeTest())); XPathExpressionPtr step(new TestStepExpression(CHILD, new AnyNodeTest()));
XPathValuePtr value = step->evaluate(root_); XPathValuePtr<std::string> value = step->evaluate(root_);
const NodeSet<std::string>& set = value->asNodeSet(); const NodeSet<std::string>& set = value->asNodeSet();
assertEquals(set.size(), 3); assertEquals(set.size(), 3);
@ -87,7 +87,7 @@ public:
{ {
XPathExpressionPtr step(new TestStepExpression(CHILD, new NameNodeTest("child2"))); XPathExpressionPtr step(new TestStepExpression(CHILD, new NameNodeTest("child2")));
XPathValuePtr value = step->evaluate(root_); XPathValuePtr<std::string> value = step->evaluate(root_);
const NodeSet<std::string>& set = value->asNodeSet(); const NodeSet<std::string>& set = value->asNodeSet();
assertEquals(1, set.size()); assertEquals(1, set.size());

View file

@ -121,7 +121,7 @@ public:
void test11() void test11()
{ {
XPathExpressionPtr nt(new NumericValue(1.0)); XPathExpressionPtr nt(new NumericValue(1.0));
XPathValuePtr ns = nt->evaluate(dummy_); XPathValuePtr<std::string> ns = nt->evaluate(dummy_);
assertTrue(areEqual(ns, (nt->evaluate(dummy_)))); assertTrue(areEqual(ns, (nt->evaluate(dummy_))));
} // test11 } // test11