parameterised XPathValue and XPathValuePtr

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

View file

@ -14,8 +14,8 @@ public:
PlusOperator(XPathExpression* lhs, XPathExpression* rhs) :
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

View file

@ -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&);

View file

@ -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&);

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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)));

View file

@ -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) ||

View file

@ -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

View file

@ -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(); }

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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());

View file

@ -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()
{

View file

@ -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

View file

@ -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());

View file

@ -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