2005-08-04 22:42:30 +02:00
|
|
|
#ifndef ARABICA_XPATHIC_XPATH_VALUE_H
|
|
|
|
#define ARABICA_XPATHIC_XPATH_VALUE_H
|
|
|
|
|
|
|
|
#include <string>
|
2007-09-05 00:55:47 +02:00
|
|
|
#include <DOM/Node.hpp>
|
2005-08-04 22:42:30 +02:00
|
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
#include <vector>
|
2007-09-10 19:52:04 +02:00
|
|
|
#include <Arabica/StringAdaptor.hpp>
|
2005-08-04 22:42:30 +02:00
|
|
|
#include "xpath_object.hpp"
|
2005-08-16 13:40:56 +02:00
|
|
|
#include "xpath_expression.hpp"
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
namespace Arabica
|
|
|
|
{
|
|
|
|
namespace XPath
|
|
|
|
{
|
|
|
|
|
2007-07-19 19:01:31 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
Some time ago, it was gently suggested to me that XPathValuePtr and XPathExpressionPtr both exposed an implementation detail, because they derive fromboost::shared_ptr, and provided an interface that was inconsisted with the DOM classes, because you accessed the member functions via -> rather than .
At the time, I was just pleased to have got the XPath stuff done and wasn't really fussed, so I left it. Since then though, it's niggled and niggled away at the back of my mind and now I've decided to do something about it.
XPathValuePtr will become XPathValue, with the member functions accessed through the . operator. The XPathValuePtr name and -> member access will be retained for the meantime, so that existing code won't be broken. XPathExpressionPtr will be similarly changed.
This commit is the first bit of that work, now I've satisfied myself it's going to be pretty easy so long as I pay proper attention.
2007-10-19 23:59:24 +02:00
|
|
|
class BoolValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
BoolValue(bool value) :
|
|
|
|
value_(value) { }
|
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
static XPathValue<string_type, string_adaptor> createValue(bool value) { return XPathValue<string_type, string_adaptor>(new BoolValue(value)); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-17 12:13:05 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2007-10-22 19:42:50 +02:00
|
|
|
return XPathValue<string_type, string_adaptor>(new BoolValue(value_));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context) { return asBool(); }
|
|
|
|
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context) { return asNumber(); }
|
|
|
|
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context) { return asString(); }
|
|
|
|
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& context) { return asNodeSet(); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
virtual bool asBool() const { return value_; }
|
|
|
|
virtual double asNumber() const { return value_ ? 1 : 0; }
|
2005-09-30 23:36:11 +02:00
|
|
|
virtual string_type asString() const { return string_adaptor::construct_from_utf8(value_ ? "true" : "false"); }
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const { static NodeSet<string_type, string_adaptor> empty; return empty; }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
virtual ValueType type() const { return BOOL; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool value_;
|
|
|
|
}; // class BoolValue
|
|
|
|
|
2007-07-19 19:01:31 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
Some time ago, it was gently suggested to me that XPathValuePtr and XPathExpressionPtr both exposed an implementation detail, because they derive fromboost::shared_ptr, and provided an interface that was inconsisted with the DOM classes, because you accessed the member functions via -> rather than .
At the time, I was just pleased to have got the XPath stuff done and wasn't really fussed, so I left it. Since then though, it's niggled and niggled away at the back of my mind and now I've decided to do something about it.
XPathValuePtr will become XPathValue, with the member functions accessed through the . operator. The XPathValuePtr name and -> member access will be retained for the meantime, so that existing code won't be broken. XPathExpressionPtr will be similarly changed.
This commit is the first bit of that work, now I've satisfied myself it's going to be pretty easy so long as I pay proper attention.
2007-10-19 23:59:24 +02:00
|
|
|
class NumericValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
NumericValue(double value) :
|
|
|
|
value_(value) { }
|
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
static XPathValue<string_type, string_adaptor> createValue(double value) { return XPathValue<string_type, string_adaptor>(new NumericValue(value)); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-17 12:13:05 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
return createValue(value_);
|
|
|
|
} // evaluate
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context) { return asBool(); }
|
|
|
|
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context) { return asNumber(); }
|
|
|
|
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context) { return asString(); }
|
|
|
|
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet(const DOM::Node<string_type, string_adaptor>& context) { return asNodeSet(); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-07-19 19:01:31 +02:00
|
|
|
virtual bool asBool() const
|
|
|
|
{
|
|
|
|
if(isNaN(value_))
|
|
|
|
return false;
|
|
|
|
return (value_ != 0.0);
|
|
|
|
} // asBool
|
2005-08-04 22:42:30 +02:00
|
|
|
virtual double asNumber() const { return value_; }
|
2005-08-17 09:01:27 +02:00
|
|
|
virtual string_type asString() const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
if(isNaN(value_))
|
2005-09-30 23:36:11 +02:00
|
|
|
return string_adaptor::construct_from_utf8("NaN");
|
2005-08-04 22:42:30 +02:00
|
|
|
if(isInfinity(value_))
|
2005-09-30 23:36:11 +02:00
|
|
|
return string_adaptor::construct_from_utf8("Infinity");
|
2005-08-04 22:42:30 +02:00
|
|
|
if(isNegativeInfinity(value_))
|
2005-09-30 23:36:11 +02:00
|
|
|
return string_adaptor::construct_from_utf8("-Infinity");
|
|
|
|
return string_adaptor::construct_from_utf8(boost::lexical_cast<std::string>(value_).c_str());
|
2005-08-04 22:42:30 +02:00
|
|
|
} // asString
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const { static NodeSet<string_type, string_adaptor> empty; return empty; }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
virtual ValueType type() const { return NUMBER; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
double value_;
|
|
|
|
}; // class NumberValue
|
|
|
|
|
2007-07-19 19:01:31 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
Some time ago, it was gently suggested to me that XPathValuePtr and XPathExpressionPtr both exposed an implementation detail, because they derive fromboost::shared_ptr, and provided an interface that was inconsisted with the DOM classes, because you accessed the member functions via -> rather than .
At the time, I was just pleased to have got the XPath stuff done and wasn't really fussed, so I left it. Since then though, it's niggled and niggled away at the back of my mind and now I've decided to do something about it.
XPathValuePtr will become XPathValue, with the member functions accessed through the . operator. The XPathValuePtr name and -> member access will be retained for the meantime, so that existing code won't be broken. XPathExpressionPtr will be similarly changed.
This commit is the first bit of that work, now I've satisfied myself it's going to be pretty easy so long as I pay proper attention.
2007-10-19 23:59:24 +02:00
|
|
|
class StringValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
StringValue(const char* value) :
|
2005-09-30 23:36:11 +02:00
|
|
|
value_(string_adaptor::construct_from_utf8(value)) { }
|
2005-08-17 10:25:24 +02:00
|
|
|
StringValue(const string_type& value) :
|
2005-08-04 22:42:30 +02:00
|
|
|
value_(value) { }
|
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
static XPathValue<string_type, string_adaptor> createValue(const string_type& value) { return XPathValue<string_type, string_adaptor>(new StringValue(value)); }
|
2007-07-19 19:01:31 +02:00
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-17 12:13:05 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2007-10-22 19:42:50 +02:00
|
|
|
return XPathValue<string_type, string_adaptor>(new StringValue(value_));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context) { return asBool(); }
|
|
|
|
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context) { return asNumber(); }
|
|
|
|
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context) { return asString(); }
|
|
|
|
virtual NodeSet<string_type, string_adaptor> evaluateAsNodeSet() const { return asNodeSet(); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-09-08 23:43:21 +02:00
|
|
|
virtual bool asBool() const { return !string_adaptor::empty(value_); }
|
2005-08-04 22:42:30 +02:00
|
|
|
virtual double asNumber() const
|
|
|
|
{
|
2007-07-19 19:01:31 +02:00
|
|
|
return impl::stringAsNumber<string_type, string_adaptor>(value_);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // asNumber
|
2005-08-17 10:25:24 +02:00
|
|
|
virtual string_type asString() const { return value_; }
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const { static NodeSet<string_type, string_adaptor> empty; return empty; }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
virtual ValueType type() const { return STRING; }
|
|
|
|
|
|
|
|
private:
|
2005-08-17 10:25:24 +02:00
|
|
|
string_type value_;
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class StringValue
|
|
|
|
|
2007-07-19 19:01:31 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
Some time ago, it was gently suggested to me that XPathValuePtr and XPathExpressionPtr both exposed an implementation detail, because they derive fromboost::shared_ptr, and provided an interface that was inconsisted with the DOM classes, because you accessed the member functions via -> rather than .
At the time, I was just pleased to have got the XPath stuff done and wasn't really fussed, so I left it. Since then though, it's niggled and niggled away at the back of my mind and now I've decided to do something about it.
XPathValuePtr will become XPathValue, with the member functions accessed through the . operator. The XPathValuePtr name and -> member access will be retained for the meantime, so that existing code won't be broken. XPathExpressionPtr will be similarly changed.
This commit is the first bit of that work, now I've satisfied myself it's going to be pretty easy so long as I pay proper attention.
2007-10-19 23:59:24 +02:00
|
|
|
class NodeSetValue : public XPathValue_impl<string_type, string_adaptor>, public XPathExpression<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2007-09-08 01:52:30 +02:00
|
|
|
NodeSetValue(const NodeSet<string_type, string_adaptor>& set) : set_(set) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
static XPathValue<string_type, string_adaptor> createValue(const NodeSet<string_type, string_adaptor>& set)
|
2007-07-19 19:01:31 +02:00
|
|
|
{
|
2007-10-22 19:42:50 +02:00
|
|
|
return XPathValue<string_type, string_adaptor>(new NodeSetValue(set));
|
2007-07-19 19:01:31 +02:00
|
|
|
} // createValue
|
|
|
|
|
2007-10-22 19:42:50 +02:00
|
|
|
virtual XPathValue<string_type, string_adaptor> evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-17 12:13:05 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2007-10-22 19:42:50 +02:00
|
|
|
return XPathValue<string_type, string_adaptor>(this);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual bool evaluateAsBool(const DOM::Node<string_type, string_adaptor>& context) const{ return asBool(); }
|
|
|
|
virtual double evaluateAsNumber(const DOM::Node<string_type, string_adaptor>& context) const { return asNumber(); }
|
|
|
|
virtual string_type evaluateAsString(const DOM::Node<string_type, string_adaptor>& context) const { return asString(); }
|
|
|
|
virtual const NodeSet<string_type, string_adaptor>& evaluateAsNodeSet() const { return asNodeSet(); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
virtual bool asBool() const
|
|
|
|
{
|
|
|
|
return !set_.empty();
|
|
|
|
} // asBool
|
|
|
|
virtual double asNumber() const
|
|
|
|
{
|
2007-07-19 19:01:31 +02:00
|
|
|
return impl::stringAsNumber<string_type, string_adaptor>(asString());
|
2005-08-04 22:42:30 +02:00
|
|
|
} // asNumber
|
2005-08-17 10:31:47 +02:00
|
|
|
virtual string_type asString() const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2007-07-19 19:01:31 +02:00
|
|
|
if(set_.empty())
|
|
|
|
return string_adaptor::construct_from_utf8("");
|
|
|
|
return impl::nodeStringValue<string_type, string_adaptor>(set_.top());
|
2005-08-04 22:42:30 +02:00
|
|
|
} // asStringx
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual const NodeSet<string_type, string_adaptor>& asNodeSet() const
|
2007-07-19 19:01:31 +02:00
|
|
|
{
|
|
|
|
return set_;
|
|
|
|
} // asNodeSet
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
virtual ValueType type() const { return NODE_SET; }
|
|
|
|
|
|
|
|
private:
|
2007-09-08 01:52:30 +02:00
|
|
|
mutable NodeSet<string_type, string_adaptor> set_;
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // NodeSetValue
|
|
|
|
|
|
|
|
} // namespace XPath
|
|
|
|
} // namespace Arabica
|
|
|
|
|
|
|
|
#endif
|