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-09-08 01:52:30 +02:00
|
|
|
static XPathValuePtr<string_type, string_adaptor> createValue(bool value) { return XPathValuePtr<string_type, string_adaptor>(new BoolValue(value)); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual XPathValuePtr<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-09-08 01:52:30 +02:00
|
|
|
return XPathValuePtr<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-09-08 01:52:30 +02:00
|
|
|
static XPathValuePtr<string_type, string_adaptor> createValue(double value) { return XPathValuePtr<string_type, string_adaptor>(new NumericValue(value)); }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual XPathValuePtr<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-09-08 01:52:30 +02:00
|
|
|
static XPathValuePtr<string_type, string_adaptor> createValue(const string_type& value) { return XPathValuePtr<string_type, string_adaptor>(new StringValue(value)); }
|
2007-07-19 19:01:31 +02:00
|
|
|
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual XPathValuePtr<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-09-08 01:52:30 +02:00
|
|
|
return XPathValuePtr<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-09-08 01:52:30 +02:00
|
|
|
static XPathValuePtr<string_type, string_adaptor> createValue(const NodeSet<string_type, string_adaptor>& set)
|
2007-07-19 19:01:31 +02:00
|
|
|
{
|
2007-09-08 01:52:30 +02:00
|
|
|
return XPathValuePtr<string_type, string_adaptor>(new NodeSetValue(set));
|
2007-07-19 19:01:31 +02:00
|
|
|
} // createValue
|
|
|
|
|
2007-09-08 01:52:30 +02:00
|
|
|
virtual XPathValuePtr<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-09-08 01:52:30 +02:00
|
|
|
return XPathValuePtr<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
|