mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-30 08:38:15 +01:00
parameterised XPathValue and XPathValuePtr
This commit is contained in:
parent
ffffbff9ce
commit
a71eb0345f
21 changed files with 533 additions and 511 deletions
|
@ -14,8 +14,8 @@ public:
|
|||
PlusOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 NumericValue::createValue(lhs()->evaluateAsNumber(context) + rhs()->evaluateAsNumber(context));
|
||||
} // evaluate
|
||||
|
@ -27,8 +27,8 @@ public:
|
|||
MinusOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 NumericValue::createValue(lhs()->evaluateAsNumber(context) - rhs()->evaluateAsNumber(context));
|
||||
} // evaluate
|
||||
|
@ -40,8 +40,8 @@ public:
|
|||
MultiplyOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 NumericValue::createValue(lhs()->evaluateAsNumber(context) * rhs()->evaluateAsNumber(context));
|
||||
} // evaluate
|
||||
|
@ -53,8 +53,8 @@ public:
|
|||
DivideOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 NumericValue::createValue(lhs()->evaluateAsNumber(context) / rhs()->evaluateAsNumber(context));
|
||||
} // evaluate
|
||||
|
@ -66,8 +66,8 @@ public:
|
|||
ModOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 NumericValue::createValue(static_cast<long>(lhs()->evaluateAsNumber(context)) % static_cast<long>(rhs()->evaluateAsNumber(context)));
|
||||
} // evaluate
|
||||
|
@ -79,8 +79,8 @@ public:
|
|||
UnaryNegative(XPathExpression* expr) :
|
||||
UnaryExpression(expr) { }
|
||||
|
||||
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 NumericValue::createValue(-expr()->evaluate(context, executionContext)->asNumber());
|
||||
} // evaluate
|
||||
|
|
|
@ -30,14 +30,14 @@ public:
|
|||
|
||||
void setPosition(unsigned int pos) { position_ = pos; }
|
||||
|
||||
const VariableResolver& variableResolver() const { return variableResolver_.get(); }
|
||||
void setVariableResolver(const VariableResolver& resolver) { variableResolver_.set(resolver); }
|
||||
void setVariableResolver(VariableResolverPtr& resolver) { variableResolver_.set(resolver); }
|
||||
const VariableResolver<std::string>& variableResolver() const { return variableResolver_.get(); }
|
||||
void setVariableResolver(const VariableResolver<std::string>& resolver) { variableResolver_.set(resolver); }
|
||||
void setVariableResolver(VariableResolverPtr<std::string>& resolver) { variableResolver_.set(resolver); }
|
||||
|
||||
private:
|
||||
size_t position_;
|
||||
size_t last_;
|
||||
ResolverHolder<const VariableResolver> variableResolver_;
|
||||
ResolverHolder<const VariableResolver<std::string> > variableResolver_;
|
||||
|
||||
ExecutionContext(const ExecutionContext&);
|
||||
ExecutionContext& operator=(const ExecutionContext&);
|
||||
|
|
|
@ -19,7 +19,7 @@ protected:
|
|||
public:
|
||||
virtual ~XPathExpression() { }
|
||||
|
||||
XPathValuePtr evaluate(const DOM::Node<std::string>& context) const
|
||||
XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context) const
|
||||
{
|
||||
ExecutionContext 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 NodeSet<std::string> evaluateAsNodeSet(const DOM::Node<std::string>& context) const { return evaluate(context)->asNodeSet(); }
|
||||
|
||||
virtual XPathValuePtr evaluate(const DOM::Node<std::string>& context,
|
||||
const Arabica::XPath::ExecutionContext& executionContext) const = 0;
|
||||
virtual XPathValuePtr<std::string> evaluate(const DOM::Node<std::string>& context,
|
||||
const Arabica::XPath::ExecutionContext& executionContext) const = 0;
|
||||
|
||||
private:
|
||||
XPathExpression(const XPathExpression&);
|
||||
|
|
|
@ -27,8 +27,8 @@ protected:
|
|||
public:
|
||||
virtual ~XPathFunction() { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const = 0;
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const = 0;
|
||||
|
||||
protected:
|
||||
size_t argCount() const { return args_.size(); }
|
||||
|
@ -73,8 +73,8 @@ class LastFn : public XPathFunction
|
|||
public:
|
||||
LastFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new NumericValue(executionContext.last());
|
||||
} // evaluate
|
||||
|
@ -86,8 +86,8 @@ class PositionFn : public XPathFunction
|
|||
public:
|
||||
PositionFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new NumericValue(executionContext.position());
|
||||
} // evaluate
|
||||
|
@ -99,8 +99,8 @@ class CountFn : public XPathFunction
|
|||
public:
|
||||
CountFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new NumericValue(argAsNodeSet(0, context, executionContext).size());
|
||||
} // evaluate
|
||||
|
@ -113,8 +113,8 @@ class LocalNameFn : public XPathFunction
|
|||
public:
|
||||
LocalNameFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
DOM::Node<std::string> node;
|
||||
if(argCount() == 0)
|
||||
|
@ -146,8 +146,8 @@ class NamespaceURIFn : public XPathFunction
|
|||
public:
|
||||
NamespaceURIFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
DOM::Node<std::string> node;
|
||||
if(argCount() == 0)
|
||||
|
@ -178,8 +178,8 @@ class NameFn : public XPathFunction
|
|||
public:
|
||||
NameFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
DOM::Node<std::string> node;
|
||||
if(argCount() == 0)
|
||||
|
@ -214,8 +214,8 @@ class StringFn : public XPathFunction
|
|||
public:
|
||||
StringFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new StringValue((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context));
|
||||
} // evaluate
|
||||
|
@ -227,8 +227,8 @@ class ConcatFn : public XPathFunction
|
|||
public:
|
||||
ConcatFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, -1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
std::string s;
|
||||
for(size_t a = 0, ae = argCount(); a < ae; ++a)
|
||||
|
@ -243,8 +243,8 @@ class StartsWithFn : public XPathFunction
|
|||
public:
|
||||
StartsWithFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
std::string value = argAsString(0, context, executionContext);
|
||||
std::string start = argAsString(1, context, executionContext);
|
||||
|
@ -266,8 +266,8 @@ class ContainsFn : public XPathFunction
|
|||
public:
|
||||
ContainsFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new BoolValue(argAsString(0, context, executionContext).find(argAsString(1, context, executionContext)) != std::string::npos);
|
||||
} // evaluate
|
||||
|
@ -279,8 +279,8 @@ class SubstringBeforeFn : public XPathFunction
|
|||
public:
|
||||
SubstringBeforeFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
std::string value = argAsString(0, context, executionContext);
|
||||
size_t splitAt = value.find(argAsString(1, context, executionContext));
|
||||
|
@ -298,8 +298,8 @@ class SubstringAfterFn : public XPathFunction
|
|||
public:
|
||||
SubstringAfterFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 2, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
std::string value = argAsString(0, context, executionContext);
|
||||
std::string split = argAsString(1, context, executionContext);
|
||||
|
@ -318,8 +318,8 @@ class SubstringFn : public XPathFunction
|
|||
public:
|
||||
SubstringFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(2, 3, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
std::string value = argAsString(0, context, executionContext);
|
||||
double startAt = roundNumber(argAsNumber(1, context, executionContext)) - 1;
|
||||
|
@ -343,8 +343,8 @@ class StringLengthFn : public XPathFunction
|
|||
public:
|
||||
StringLengthFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new NumericValue(((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context)).length());
|
||||
} // evaluate
|
||||
|
@ -356,8 +356,8 @@ class NormalizeSpaceFn : public XPathFunction
|
|||
public:
|
||||
NormalizeSpaceFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
std::string value = ((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context));
|
||||
size_t i = 0, ie = value.length();
|
||||
|
@ -389,8 +389,8 @@ class TranslateFn : public XPathFunction
|
|||
public:
|
||||
TranslateFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(3, 3, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
std::string str = argAsString(0, context, executionContext);
|
||||
std::string from = argAsString(1, context, executionContext);
|
||||
|
@ -421,8 +421,8 @@ class BooleanFn : public XPathFunction
|
|||
public:
|
||||
BooleanFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new BoolValue(argAsBool(0, context, executionContext));
|
||||
} // evaluate
|
||||
|
@ -434,8 +434,8 @@ class NotFn : public XPathFunction
|
|||
public:
|
||||
NotFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new BoolValue(!argAsBool(0, context, executionContext));
|
||||
}
|
||||
|
@ -447,8 +447,8 @@ class TrueFn : public XPathFunction
|
|||
public:
|
||||
TrueFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new BoolValue(true);
|
||||
} // evaluate
|
||||
|
@ -460,8 +460,8 @@ class FalseFn : public XPathFunction
|
|||
public:
|
||||
FalseFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 0, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new BoolValue(false);
|
||||
} // evaluate
|
||||
|
@ -478,8 +478,8 @@ class NumberFn : public XPathFunction
|
|||
public:
|
||||
NumberFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(0, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
double result = (argCount() > 0) ? argAsNumber(0, context, executionContext) :
|
||||
StringValue(nodeStringValue(context)).asNumber();
|
||||
|
@ -493,8 +493,8 @@ class SumFn : public XPathFunction
|
|||
public:
|
||||
SumFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
double sum = 0;
|
||||
NodeSet<std::string> ns = argAsNodeSet(0, context, executionContext);
|
||||
|
@ -510,8 +510,8 @@ class FloorFn : public XPathFunction
|
|||
public:
|
||||
FloorFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new NumericValue(std::floor(argAsNumber(0, context, executionContext)));
|
||||
} // evaluate
|
||||
|
@ -523,8 +523,8 @@ class CeilingFn : public XPathFunction
|
|||
public:
|
||||
CeilingFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new NumericValue(std::ceil(argAsNumber(0, context, executionContext)));
|
||||
} // evaluate
|
||||
|
@ -536,8 +536,8 @@ class RoundFn : public XPathFunction
|
|||
public:
|
||||
RoundFn(const std::vector<XPathExpressionPtr>& args) : XPathFunction(1, 1, args) { }
|
||||
|
||||
virtual XPathValue* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
|
||||
const ExecutionContext& executionContext) const
|
||||
{
|
||||
return new NumericValue(roundNumber(argAsNumber(0, context, executionContext)));
|
||||
} // evaluate
|
||||
|
|
|
@ -62,10 +62,10 @@ public:
|
|||
delete func_;
|
||||
} // ~FunctionHolder
|
||||
|
||||
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(func_->evaluate(context, executionContext));
|
||||
return XPathValuePtr<std::string>(func_->evaluate(context, executionContext));
|
||||
} // evaluate
|
||||
|
||||
static FunctionHolder* createFunction(const std::string& name,
|
||||
|
|
|
@ -14,8 +14,8 @@ public:
|
|||
OrOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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
|
||||
{
|
||||
// From XPath 1.0 Rec, section 3.4
|
||||
// An or expression is evaluated by evaluating each operand and converting its value
|
||||
|
@ -34,8 +34,8 @@ public:
|
|||
AndOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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
|
||||
{
|
||||
// From XPath 1.0 Rec, section 3.4
|
||||
// An and expression is evaluated by evaluating each operand and converting its value
|
||||
|
|
|
@ -99,6 +99,7 @@ private:
|
|||
bool sorted_;
|
||||
}; // NodeSet
|
||||
|
||||
template<class string_type>
|
||||
class XPathValue
|
||||
{
|
||||
protected:
|
||||
|
@ -109,8 +110,8 @@ public:
|
|||
|
||||
virtual bool asBool() const = 0;
|
||||
virtual double asNumber() const = 0;
|
||||
virtual std::string asString() const = 0;
|
||||
virtual const NodeSet<std::string>& asNodeSet() const = 0;
|
||||
virtual string_type asString() const = 0;
|
||||
virtual const NodeSet<string_type>& asNodeSet() const = 0;
|
||||
|
||||
virtual ValueType type() const = 0;
|
||||
|
||||
|
@ -120,10 +121,11 @@ private:
|
|||
XPathValue& operator=(const 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:
|
||||
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);
|
||||
|
@ -147,15 +149,61 @@ inline double roundNumber(double value)
|
|||
return value;
|
||||
} // roundNumber
|
||||
|
||||
double stringAsNumber(const std::string& str);
|
||||
double nodeNumberValue(const DOM::Node<std::string>& node);
|
||||
std::string nodeStringValue(const DOM::Node<std::string>& node);
|
||||
template<class string_type>
|
||||
double stringAsNumber(const string_type& str)
|
||||
{
|
||||
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);
|
||||
bool isLessThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs);
|
||||
bool isLessThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs);
|
||||
bool isGreaterThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs);
|
||||
bool isGreaterThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs);
|
||||
template<class string_type>
|
||||
double nodeNumberValue(const DOM::Node<string_type>& node)
|
||||
{
|
||||
return stringAsNumber(nodeStringValue(node));
|
||||
} // 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 Arabica
|
||||
|
|
|
@ -47,18 +47,18 @@ public:
|
|||
XPathExpressionPtr compile(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 evaluate_expr(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<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(NamespaceContextPtr namespaceContext) { namespaceContext_.set(namespaceContext); }
|
||||
const NamespaceContext& getNamespaceContext() const { return namespaceContext_.get(); }
|
||||
void resetNamespaceContext() { namespaceContext_.set(NamespaceContextPtr(new NullNamespaceContext())); }
|
||||
|
||||
void setVariableResolver(const VariableResolver& variableResolver) { variableResolver_.set(variableResolver); }
|
||||
void setVariableResolver(VariableResolverPtr variableResolver) { variableResolver_.set(variableResolver); }
|
||||
const VariableResolver& getVariableResolver() const { return variableResolver_.get(); }
|
||||
void resetVariableResolver() { variableResolver_.set(VariableResolverPtr(new NullVariableResolver())); }
|
||||
void setVariableResolver(const VariableResolver<std::string>& variableResolver) { variableResolver_.set(variableResolver); }
|
||||
void setVariableResolver(VariableResolverPtr<std::string> variableResolver) { variableResolver_.set(variableResolver); }
|
||||
const VariableResolver<std::string>& getVariableResolver() const { return variableResolver_.get(); }
|
||||
void resetVariableResolver() { variableResolver_.set(VariableResolverPtr<std::string>(new NullVariableResolver<std::string>())); }
|
||||
|
||||
void setFunctionResolver(const FunctionResolver& functionResolver) { functionResolver_.set(functionResolver); }
|
||||
void setFunctionResolver(FunctionResolverPtr functionResolver) { functionResolver_.set(functionResolver); }
|
||||
|
@ -73,7 +73,7 @@ private:
|
|||
xpath_grammar xpathg_;
|
||||
|
||||
ResolverHolder<const NamespaceContext> namespaceContext_;
|
||||
ResolverHolder<const VariableResolver> variableResolver_;
|
||||
ResolverHolder<const VariableResolver<std::string> > variableResolver_;
|
||||
ResolverHolder<const FunctionResolver> functionResolver_;
|
||||
|
||||
typedef XPathExpression* (*compileFn)(node_iter_t const& i, CompilationContext& context);
|
||||
|
|
|
@ -14,8 +14,8 @@ public:
|
|||
EqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 BoolValue::createValue(areEqual(lhs()->evaluate(context, executionContext),
|
||||
rhs()->evaluate(context, executionContext)));
|
||||
|
@ -28,8 +28,8 @@ public:
|
|||
NotEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 BoolValue::createValue(!areEqual(lhs()->evaluate(context, executionContext),
|
||||
rhs()->evaluate(context, executionContext)));
|
||||
|
@ -42,8 +42,8 @@ public:
|
|||
LessThanOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 BoolValue::createValue(isLessThan(lhs()->evaluate(context, executionContext),
|
||||
rhs()->evaluate(context, executionContext)));
|
||||
|
@ -56,8 +56,8 @@ public:
|
|||
LessThanEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 BoolValue::createValue(isLessThanEquals(lhs()->evaluate(context, executionContext),
|
||||
rhs()->evaluate(context, executionContext)));
|
||||
|
@ -70,8 +70,8 @@ public:
|
|||
GreaterThanOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 BoolValue::createValue(isGreaterThan(lhs()->evaluate(context, executionContext),
|
||||
rhs()->evaluate(context, executionContext)));
|
||||
|
@ -84,8 +84,8 @@ public:
|
|||
GreaterThanEqualsOperator(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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 BoolValue::createValue(isGreaterThanEquals(lhs()->evaluate(context, executionContext),
|
||||
rhs()->evaluate(context, executionContext)));
|
||||
|
|
|
@ -29,8 +29,8 @@ public:
|
|||
delete *p;
|
||||
} // ~StepExpression
|
||||
|
||||
virtual XPathValuePtr 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(const DOM::Node<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(); }
|
||||
|
||||
|
@ -52,7 +52,7 @@ private:
|
|||
for(NodeSet<std::string>::iterator i = nodes.begin(); i != nodes.end(); ++i, ++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()))
|
||||
continue;
|
||||
|
@ -89,19 +89,19 @@ public:
|
|||
delete test_;
|
||||
} // 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;
|
||||
enumerateOver(context, nodes, executionContext);
|
||||
return XPathValuePtr(new NodeSetValue(nodes));
|
||||
return XPathValuePtr<std::string>(new NodeSetValue(nodes));
|
||||
} // 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;
|
||||
for(NodeSet<std::string>::iterator n = context.begin(); n != context.end(); ++n)
|
||||
enumerateOver(*n, nodes, executionContext);
|
||||
return XPathValuePtr(new NodeSetValue(nodes));
|
||||
return XPathValuePtr<std::string>(new NodeSetValue(nodes));
|
||||
} // evaluate
|
||||
|
||||
private:
|
||||
|
@ -150,16 +150,16 @@ public:
|
|||
delete expr_;
|
||||
} // 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())
|
||||
return expr_->evaluate(context, executionContext);
|
||||
|
||||
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
|
||||
|
||||
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();
|
||||
return evaluate(c, executionContext);
|
||||
|
@ -375,18 +375,18 @@ public:
|
|||
delete *i;
|
||||
} // ~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;
|
||||
nodes.push_back(context);
|
||||
|
||||
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();
|
||||
} // for ...
|
||||
|
||||
return XPathValuePtr(new NodeSetValue(nodes));
|
||||
return XPathValuePtr<std::string>(new NodeSetValue(nodes));
|
||||
} // do_evaluate
|
||||
|
||||
private:
|
||||
|
@ -399,7 +399,7 @@ public:
|
|||
AbsoluteLocationPath(StepExpression* step) : RelativeLocationPath(step) { }
|
||||
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();
|
||||
if((type == DOM::Node<std::string>::DOCUMENT_NODE) ||
|
||||
|
|
|
@ -15,13 +15,13 @@ public:
|
|||
UnionExpression(XPathExpression* lhs, XPathExpression* rhs) :
|
||||
BinaryExpression(lhs, rhs) { }
|
||||
|
||||
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
|
||||
{
|
||||
XPathValuePtr p1 = lhs()->evaluate(context, executionContext);
|
||||
XPathValuePtr<std::string> p1 = lhs()->evaluate(context, executionContext);
|
||||
if(p1->type() != 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)
|
||||
throw RuntimeException("Union operator joins node-sets. First argument is not a node-set.");
|
||||
|
||||
|
@ -63,9 +63,9 @@ public:
|
|||
} // evaluate
|
||||
|
||||
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
|
||||
}; // UnionExpression
|
||||
|
||||
|
|
|
@ -13,17 +13,17 @@ namespace Arabica
|
|||
namespace XPath
|
||||
{
|
||||
|
||||
class BoolValue : public XPathValue, public XPathExpression
|
||||
class BoolValue : public XPathValue<std::string>, public XPathExpression
|
||||
{
|
||||
public:
|
||||
BoolValue(bool 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
|
||||
virtual bool evaluateAsBool(const DOM::Node<std::string>& context) { return asBool(); }
|
||||
virtual double evaluateAsNumber(const DOM::Node<std::string>& context) { return asNumber(); }
|
||||
|
@ -41,15 +41,15 @@ private:
|
|||
bool value_;
|
||||
}; // class BoolValue
|
||||
|
||||
class NumericValue : public XPathValue, public XPathExpression
|
||||
class NumericValue : public XPathValue<std::string>, public XPathExpression
|
||||
{
|
||||
public:
|
||||
NumericValue(double 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_);
|
||||
} // evaluate
|
||||
|
@ -78,7 +78,7 @@ private:
|
|||
double value_;
|
||||
}; // class NumberValue
|
||||
|
||||
class StringValue : public XPathValue, public XPathExpression
|
||||
class StringValue : public XPathValue<std::string>, public XPathExpression
|
||||
{
|
||||
public:
|
||||
StringValue(const char* value) :
|
||||
|
@ -86,9 +86,9 @@ public:
|
|||
StringValue(const std::string& 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
|
||||
virtual bool evaluateAsBool(const DOM::Node<std::string>& context) { return asBool(); }
|
||||
virtual double evaluateAsNumber(const DOM::Node<std::string>& context) { return asNumber(); }
|
||||
|
@ -109,14 +109,14 @@ private:
|
|||
std::string value_;
|
||||
}; // class StringValue
|
||||
|
||||
class NodeSetValue : public XPathValue, public XPathExpression
|
||||
class NodeSetValue : public XPathValue<std::string>, public XPathExpression
|
||||
{
|
||||
public:
|
||||
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
|
||||
virtual bool evaluateAsBool(const DOM::Node<std::string>& context) const{ return asBool(); }
|
||||
virtual double evaluateAsNumber(const DOM::Node<std::string>& context) const { return asNumber(); }
|
||||
|
|
|
@ -15,8 +15,8 @@ class Variable : public XPathExpression
|
|||
public:
|
||||
Variable(const std::string& name) : name_(name) { }
|
||||
|
||||
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 executionContext.variableResolver().resolveVariable(name_);
|
||||
} // evaluate
|
||||
|
|
|
@ -15,24 +15,27 @@ public:
|
|||
UnboundVariableException(const std::string& thing) : std::runtime_error("The variable '" + thing + "' is undefined.") { }
|
||||
}; // class UnboundVariableException
|
||||
|
||||
template<class string_type>
|
||||
class VariableResolver
|
||||
{
|
||||
public:
|
||||
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 VariableResolverPtr : public boost::shared_ptr<VariableResolver>
|
||||
template<class string_type>
|
||||
class VariableResolverPtr : public boost::shared_ptr<VariableResolver<string_type> >
|
||||
{
|
||||
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 NullVariableResolver : public VariableResolver
|
||||
template<class string_type>
|
||||
class NullVariableResolver : public VariableResolver<string_type>
|
||||
{
|
||||
public:
|
||||
virtual XPathValuePtr resolveVariable(const std::string& name) const
|
||||
virtual XPathValuePtr<string_type> resolveVariable(const string_type& name) const
|
||||
{
|
||||
throw UnboundVariableException(name);
|
||||
} // resolveVariable
|
||||
|
|
|
@ -9,11 +9,89 @@ namespace Arabica
|
|||
namespace XPath
|
||||
{
|
||||
|
||||
bool nodeSetsEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs);
|
||||
bool nodeSetAndValueEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs);
|
||||
template<class string_type>
|
||||
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);
|
||||
double maxValue(const NodeSet<std::string>& ns);
|
||||
if((lns.size() == 0) || (rns.size() == 0))
|
||||
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<> std::string nodeValue(const DOM::Node<std::string>& node) { return nodeStringValue(node); }
|
||||
|
@ -39,13 +117,13 @@ private:
|
|||
}; // class compareNodeWith
|
||||
|
||||
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()));
|
||||
} // compareNodeSets
|
||||
|
||||
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();
|
||||
return std::find_if(lns.begin(),
|
||||
|
@ -54,7 +132,7 @@ bool compareNodeSetWith(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
|
|||
} // 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 rt = rhs->type();
|
||||
|
@ -79,60 +157,8 @@ bool areEqual(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
|
|||
return false;
|
||||
} // 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 rt = rhs->type();
|
||||
|
@ -149,7 +175,7 @@ bool isLessThan(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
|
|||
return lhs->asNumber() < rhs->asNumber();
|
||||
} // 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 rt = rhs->type();
|
||||
|
@ -166,92 +192,17 @@ bool isLessThanEquals(const XPathValuePtr& lhs, const XPathValuePtr& rhs)
|
|||
return lhs->asNumber() <= rhs->asNumber();
|
||||
} // 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);
|
||||
} // 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);
|
||||
} // 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)
|
||||
{
|
||||
if(node.getNodeType() == DOM::Node<std::string>::ATTRIBUTE_NODE)
|
||||
|
|
|
@ -286,7 +286,7 @@ tree_info_t XPath::parse_xpath_expr(const std::string& str) const
|
|||
return ast_parse(first, last, xpathg);
|
||||
} // 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.setVariableResolver(getVariableResolver());
|
||||
|
@ -294,7 +294,7 @@ XPathValuePtr XPath::evaluate(const std::string& xpath, const DOM::Node<std::str
|
|||
return compile(xpath)->evaluate(context, executionContext);
|
||||
} // 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.setVariableResolver(getVariableResolver());
|
||||
|
|
|
@ -43,7 +43,7 @@ bool imbueInput(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))
|
||||
{
|
||||
|
@ -63,6 +63,26 @@ int main(int argc, const char* argv[])
|
|||
|
||||
return 0;
|
||||
} // 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()
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ int main(int argc, char* argv[])
|
|||
if(!eh.errorsReported())
|
||||
{
|
||||
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())
|
||||
std::cout << file << std::endl;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -57,7 +57,7 @@ public:
|
|||
{
|
||||
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();
|
||||
|
||||
assertEquals(set.size(), 3);
|
||||
|
@ -87,7 +87,7 @@ public:
|
|||
{
|
||||
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();
|
||||
|
||||
assertEquals(1, set.size());
|
||||
|
|
|
@ -121,7 +121,7 @@ public:
|
|||
void test11()
|
||||
{
|
||||
XPathExpressionPtr nt(new NumericValue(1.0));
|
||||
XPathValuePtr ns = nt->evaluate(dummy_);
|
||||
XPathValuePtr<std::string> ns = nt->evaluate(dummy_);
|
||||
|
||||
assertTrue(areEqual(ns, (nt->evaluate(dummy_))));
|
||||
} // test11
|
||||
|
|
Loading…
Add table
Reference in a new issue