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) :
|
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
|
||||||
|
|
|
@ -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&);
|
||||||
|
|
|
@ -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&);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
|
@ -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) ||
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
@ -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());
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue