2005-08-04 22:42:30 +02:00
|
|
|
#ifndef ARABICA_XPATH_FUNCTION_HPP
|
|
|
|
#define ARABICA_XPATH_FUNCTION_HPP
|
|
|
|
|
|
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
#include <cmath>
|
2007-09-05 00:55:47 +02:00
|
|
|
#include <XML/XMLCharacterClasses.hpp>
|
2007-09-10 19:24:17 +02:00
|
|
|
#include <text/UnicodeCharacters.hpp>
|
|
|
|
#include <text/normalize_whitespace.hpp>
|
2005-08-04 22:42:30 +02:00
|
|
|
#include "xpath_value.hpp"
|
|
|
|
#include "xpath_execution_context.hpp"
|
|
|
|
|
|
|
|
namespace Arabica
|
|
|
|
{
|
|
|
|
namespace XPath
|
|
|
|
{
|
|
|
|
|
2007-09-09 00:31:24 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
2005-08-04 22:42:30 +02:00
|
|
|
class XPathFunction
|
|
|
|
{
|
|
|
|
protected:
|
2005-08-18 11:00:35 +02:00
|
|
|
XPathFunction(int minArgs, int maxArgs, const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) :
|
2005-08-04 22:42:30 +02:00
|
|
|
args_(args)
|
|
|
|
{
|
|
|
|
if(((minArgs != -1) && (static_cast<int>(args.size()) < minArgs)) ||
|
|
|
|
((maxArgs != -1) && (static_cast<int>(args.size()) > maxArgs)))
|
|
|
|
throw SyntaxException("wrong number of arguments to function");
|
|
|
|
} // XPathFunction
|
|
|
|
|
|
|
|
public:
|
|
|
|
virtual ~XPathFunction() { }
|
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:00:35 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
size_t argCount() const { return args_.size(); }
|
|
|
|
|
2007-09-08 01:52:30 +02:00
|
|
|
XPathValuePtr<string_type, string_adaptor> arg(size_t index,
|
|
|
|
const DOM::Node<string_type, string_adaptor>& context,
|
2007-07-19 19:01:31 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
|
|
|
{
|
|
|
|
return args_[index]->evaluate(context, executionContext);
|
|
|
|
} // argAsBool
|
|
|
|
|
2005-08-04 22:42:30 +02:00
|
|
|
bool argAsBool(size_t index,
|
2007-09-08 01:52:30 +02:00
|
|
|
const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:00:35 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
return args_[index]->evaluate(context, executionContext)->asBool();
|
|
|
|
} // argAsBool
|
|
|
|
|
|
|
|
double argAsNumber(size_t index,
|
2007-09-08 01:52:30 +02:00
|
|
|
const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:00:35 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
return args_[index]->evaluate(context, executionContext)->asNumber();
|
|
|
|
} // argAsNumber
|
|
|
|
|
2005-08-18 11:00:35 +02:00
|
|
|
string_type argAsString(size_t index,
|
2007-09-08 01:52:30 +02:00
|
|
|
const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:00:35 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
return args_[index]->evaluate(context, executionContext)->asString();
|
|
|
|
} // argAsString
|
|
|
|
|
2007-09-08 01:52:30 +02:00
|
|
|
NodeSet<string_type, string_adaptor> argAsNodeSet(size_t index,
|
|
|
|
const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:00:35 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
return args_[index]->evaluate(context, executionContext)->asNodeSet();
|
|
|
|
} // argAsNodeSet
|
|
|
|
|
|
|
|
private:
|
2005-08-18 11:00:35 +02:00
|
|
|
const std::vector<XPathExpressionPtr<string_type, string_adaptor> > args_;
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class XPathFunction
|
|
|
|
|
2005-08-22 17:04:27 +02:00
|
|
|
namespace impl
|
|
|
|
{
|
2005-08-04 22:42:30 +02:00
|
|
|
////////////////////////////////
|
|
|
|
// node-set functions
|
|
|
|
// number last()
|
2005-08-18 11:33:19 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class LastFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2005-08-18 11:33:19 +02:00
|
|
|
LastFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:33:19 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:33:19 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(executionContext.last());
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class LastFn
|
|
|
|
|
|
|
|
// number position()
|
2005-08-18 11:33:19 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class PositionFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2005-08-18 11:33:19 +02:00
|
|
|
PositionFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:33:19 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:33:19 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(executionContext.position());
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class PositionFn
|
|
|
|
|
|
|
|
// number count(node-set)
|
2005-08-18 11:33:19 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class CountFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:33:19 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 11:33:19 +02:00
|
|
|
CountFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:33:19 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:33:19 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(baseT::argAsNodeSet(0, context, executionContext).size());
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class CountFn
|
|
|
|
|
|
|
|
// node-set id(object)
|
|
|
|
// string local-name(node-set?)
|
2005-08-18 11:33:19 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class LocalNameFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:33:19 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 11:33:19 +02:00
|
|
|
LocalNameFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:33:19 +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
|
|
|
DOM::Node<string_type, string_adaptor> node;
|
2005-08-18 11:33:19 +02:00
|
|
|
if(baseT::argCount() == 0)
|
2005-08-04 22:42:30 +02:00
|
|
|
node = context;
|
|
|
|
else
|
|
|
|
{
|
2007-09-08 01:52:30 +02:00
|
|
|
NodeSet<string_type, string_adaptor> ns = baseT::argAsNodeSet(0, context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
if(ns.size() != 0)
|
|
|
|
node = ns.top();
|
|
|
|
} // if ...
|
|
|
|
|
|
|
|
if(node != 0)
|
|
|
|
switch(node.getNodeType())
|
|
|
|
{
|
|
|
|
case DOM::Node_base::ATTRIBUTE_NODE:
|
|
|
|
case DOM::Node_base::ELEMENT_NODE:
|
|
|
|
case DOM::Node_base::PROCESSING_INSTRUCTION_NODE:
|
2005-08-18 11:33:19 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(node.hasNamespaceURI() ? node.getLocalName() : node.getNodeName());
|
2005-08-05 22:56:15 +02:00
|
|
|
default: // put this in to keep gcc quiet
|
|
|
|
;
|
2005-08-04 22:42:30 +02:00
|
|
|
} // switch ...
|
2005-08-18 11:33:19 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>("");
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class LocalNameFn
|
|
|
|
|
|
|
|
// string namespace-uri(node-set?)
|
2005-08-18 11:33:19 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class NamespaceURIFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:33:19 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 11:33:19 +02:00
|
|
|
NamespaceURIFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:33:19 +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
|
|
|
DOM::Node<string_type, string_adaptor> node;
|
2005-08-18 11:33:19 +02:00
|
|
|
if(baseT::argCount() == 0)
|
2005-08-04 22:42:30 +02:00
|
|
|
node = context;
|
|
|
|
else
|
|
|
|
{
|
2007-09-08 01:52:30 +02:00
|
|
|
NodeSet<string_type, string_adaptor> ns = baseT::argAsNodeSet(0, context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
if(ns.size() != 0)
|
|
|
|
node = ns.top();
|
|
|
|
} // if ...
|
|
|
|
|
|
|
|
if(node != 0)
|
|
|
|
switch(node.getNodeType())
|
|
|
|
{
|
|
|
|
case DOM::Node_base::ATTRIBUTE_NODE:
|
|
|
|
case DOM::Node_base::ELEMENT_NODE:
|
2005-08-18 11:33:19 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(node.getNamespaceURI());
|
2005-08-05 22:56:15 +02:00
|
|
|
default: // put this in to keep gcc quiet
|
|
|
|
;
|
2005-08-04 22:42:30 +02:00
|
|
|
} // switch ...
|
2005-08-18 11:33:19 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>("");
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class NamespaceURIFn
|
|
|
|
|
|
|
|
// string name(node-set?)
|
2005-08-18 11:33:19 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class NameFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 11:33:19 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 11:33:19 +02:00
|
|
|
NameFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 11:33:19 +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
|
|
|
DOM::Node<string_type, string_adaptor> node;
|
2005-08-18 11:33:19 +02:00
|
|
|
if(baseT::argCount() == 0)
|
2005-08-04 22:42:30 +02:00
|
|
|
node = context;
|
|
|
|
else
|
|
|
|
{
|
2007-09-08 01:52:30 +02:00
|
|
|
NodeSet<string_type, string_adaptor> ns = baseT::argAsNodeSet(0, context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
if(ns.size() != 0)
|
|
|
|
node = ns.top();
|
|
|
|
} // if ...
|
|
|
|
|
|
|
|
if(node != 0)
|
|
|
|
switch(node.getNodeType())
|
|
|
|
{
|
|
|
|
case DOM::Node_base::ATTRIBUTE_NODE:
|
|
|
|
case DOM::Node_base::ELEMENT_NODE:
|
|
|
|
case DOM::Node_base::PROCESSING_INSTRUCTION_NODE:
|
2007-07-19 19:01:31 +02:00
|
|
|
case NAMESPACE_NODE_TYPE:
|
2005-08-18 11:33:19 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(node.getNodeName());
|
2005-08-05 22:56:15 +02:00
|
|
|
default: // stop gcc generating a warning about unhandled enum values
|
|
|
|
;
|
2005-08-04 22:42:30 +02:00
|
|
|
} // switch ...
|
2005-08-18 11:33:19 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>("");
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class NameFn
|
|
|
|
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
// string functions
|
|
|
|
|
|
|
|
// string string(object?)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class StringFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
StringFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-23 21:19:17 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>((baseT::argCount() > 0) ? baseT::argAsString(0, context, executionContext) : nodeStringValue<string_type, string_adaptor>(context));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class StringFn
|
|
|
|
|
|
|
|
// string concat(string, string, string*)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class ConcatFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
ConcatFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(2, -1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
string_type s;
|
|
|
|
for(size_t a = 0, ae = baseT::argCount(); a < ae; ++a)
|
2005-09-30 23:36:11 +02:00
|
|
|
string_adaptor::append(s, baseT::argAsString(a, context, executionContext));
|
2005-08-18 13:32:29 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(s);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // ConcatFn
|
|
|
|
|
|
|
|
// boolean starts-with(string, string)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class StartsWithFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
StartsWithFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
string_type value = baseT::argAsString(0, context, executionContext);
|
|
|
|
string_type start = baseT::argAsString(1, context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-09-30 23:36:11 +02:00
|
|
|
if(string_adaptor::length(value) < string_adaptor::length(start))
|
2005-08-18 13:32:29 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(false);
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-10-22 05:17:39 +02:00
|
|
|
typename string_adaptor::const_iterator i = string_adaptor::begin(value);
|
|
|
|
typename string_adaptor::const_iterator s = string_adaptor::begin(start);
|
|
|
|
typename string_adaptor::const_iterator e = string_adaptor::end(start);
|
2005-09-30 23:36:11 +02:00
|
|
|
for(; s != e; ++s, ++i)
|
|
|
|
if(*i != *s)
|
2005-08-18 13:32:29 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(false);
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-18 13:32:29 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(true);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // StartsWithFn
|
|
|
|
|
|
|
|
// boolean contains(string, string)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class ContainsFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
ContainsFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-09-30 23:36:11 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(string_adaptor::find(baseT::argAsString(0, context, executionContext),
|
2006-06-08 11:51:18 +02:00
|
|
|
baseT::argAsString(1, context, executionContext)) != string_adaptor::npos());
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class ContainsFn
|
|
|
|
|
|
|
|
// string substring-before(string, string)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class SubstringBeforeFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
SubstringBeforeFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
string_type value = baseT::argAsString(0, context, executionContext);
|
2005-09-30 23:36:11 +02:00
|
|
|
size_t splitAt = string_adaptor::find(value, baseT::argAsString(1, context, executionContext));
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2006-06-08 11:51:18 +02:00
|
|
|
if(splitAt == string_adaptor::npos())
|
2005-08-18 13:32:29 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>("");
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-09-30 23:36:11 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(string_adaptor::substr(value, 0, splitAt));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class SubstringBeforeFn
|
|
|
|
|
|
|
|
// string substring-after(string, string)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class SubstringAfterFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
SubstringAfterFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
string_type value = baseT::argAsString(0, context, executionContext);
|
|
|
|
string_type split = baseT::argAsString(1, context, executionContext);
|
2005-09-30 23:36:11 +02:00
|
|
|
size_t splitAt = string_adaptor::find(value, split);
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2006-06-08 11:51:18 +02:00
|
|
|
if((splitAt == string_adaptor::npos()) || ((splitAt + string_adaptor::length(split)) >= string_adaptor::length(value)))
|
2005-08-18 13:32:29 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>("");
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-09-30 23:36:11 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(string_adaptor::substr(value, splitAt + string_adaptor::length(split)));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class SubstringAfterFn
|
|
|
|
|
|
|
|
// string substring(string, number, number?)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class SubstringFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
SubstringFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(2, 3, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
string_type value = baseT::argAsString(0, context, executionContext);
|
2007-07-19 19:01:31 +02:00
|
|
|
if(string_adaptor::empty(value))
|
|
|
|
return new StringValue<string_type, string_adaptor>(value);
|
|
|
|
|
2005-08-18 13:32:29 +02:00
|
|
|
double startAt = roundNumber(baseT::argAsNumber(1, context, executionContext)) - 1;
|
|
|
|
double endAt = roundNumber((baseT::argCount() == 3 ? baseT::argAsNumber(2, context, executionContext) : Infinity)) + startAt;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-08-07 22:11:43 +02:00
|
|
|
if((endAt < 0) || (endAt < startAt) || (isNaN(endAt)))
|
2005-08-18 13:32:29 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>("");
|
2005-08-04 22:42:30 +02:00
|
|
|
|
|
|
|
if(startAt < 0)
|
|
|
|
startAt = 0;
|
2005-09-30 23:36:11 +02:00
|
|
|
if((isInfinite(endAt)) || (endAt > string_adaptor::length(value)))
|
|
|
|
endAt = string_adaptor::length(value);
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-09-30 23:36:11 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(string_adaptor::substr(value, static_cast<int>(startAt), static_cast<int>(endAt - startAt)));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // SubstringFn
|
|
|
|
|
|
|
|
// number string-length(string?)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class StringLengthFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
StringLengthFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-09-30 23:36:11 +02:00
|
|
|
string_type v = (baseT::argCount() > 0) ? baseT::argAsString(0, context, executionContext) : nodeStringValue<string_type, string_adaptor>(context);
|
|
|
|
return new NumericValue<string_type, string_adaptor>(string_adaptor::length(v));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // StringLengthFn
|
|
|
|
|
|
|
|
// string normalize-space(string?)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class NormalizeSpaceFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
NormalizeSpaceFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2006-07-13 22:47:51 +02:00
|
|
|
string_type initial = ((baseT::argCount() > 0) ? baseT::argAsString(0, context, executionContext) : nodeStringValue<string_type, string_adaptor>(context));
|
2007-09-10 19:24:17 +02:00
|
|
|
string_type value = Arabica::text::normalize_whitespace<string_type, string_adaptor>(initial);
|
2007-07-19 19:01:31 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(value);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class NormalizeSpaceFn
|
|
|
|
|
|
|
|
// string translate(string, string, string)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class TranslateFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 13:32:29 +02:00
|
|
|
TranslateFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(3, 3, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 13:32:29 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 13:32:29 +02:00
|
|
|
string_type str = baseT::argAsString(0, context, executionContext);
|
|
|
|
string_type from = baseT::argAsString(1, context, executionContext);
|
|
|
|
string_type to = baseT::argAsString(2, context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2005-10-22 05:17:39 +02:00
|
|
|
typename string_adaptor::mutable_iterator p = string_adaptor::begin(str);
|
|
|
|
for(typename string_adaptor::mutable_iterator i = string_adaptor::begin(str), ie = string_adaptor::end(str); i != ie; ++i)
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-09-30 23:36:11 +02:00
|
|
|
size_t r = string_adaptor::find(from, *i);
|
2006-06-08 11:51:18 +02:00
|
|
|
if(r == string_adaptor::npos())
|
2005-08-04 22:42:30 +02:00
|
|
|
++p;
|
2005-09-30 23:36:11 +02:00
|
|
|
else if(r < string_adaptor::length(to))
|
|
|
|
*p++ = *(string_adaptor::begin(to) + r);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // for ...
|
2005-09-30 23:36:11 +02:00
|
|
|
if(p != string_adaptor::end(str))
|
|
|
|
*p = 0;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2006-07-13 23:03:00 +02:00
|
|
|
return new StringValue<string_type, string_adaptor>(string_adaptor::construct(string_adaptor::begin(str), p));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class TranslateFn
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
|
|
// boolean functions
|
|
|
|
|
|
|
|
// boolean boolean(object)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class BooleanFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
BooleanFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(baseT::argAsBool(0, context, executionContext));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class BooleanFn
|
|
|
|
|
|
|
|
// boolean not(boolean)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class NotFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
NotFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(!baseT::argAsBool(0, context, executionContext));
|
2005-08-04 22:42:30 +02:00
|
|
|
}
|
|
|
|
}; // class NotFn
|
|
|
|
|
|
|
|
// boolean true()
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class TrueFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
TrueFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(true);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // TrueFn
|
|
|
|
|
|
|
|
// boolean false()
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class FalseFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
FalseFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(false);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // FalseFn
|
|
|
|
|
|
|
|
// boolean lang(string)
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
// number functions
|
|
|
|
|
|
|
|
// number number(object?)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class NumberFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
NumberFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
double result = (baseT::argCount() > 0) ? baseT::argAsNumber(0, context, executionContext) :
|
2005-08-23 21:19:17 +02:00
|
|
|
StringValue<string_type, string_adaptor>(nodeStringValue<string_type, string_adaptor>(context)).asNumber();
|
2005-08-18 15:18:33 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(result);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // NumberFn
|
|
|
|
|
|
|
|
// number sum(node-set)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class SumFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
SumFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
double sum = 0;
|
2007-09-08 01:52:30 +02:00
|
|
|
NodeSet<string_type, string_adaptor> ns = baseT::argAsNodeSet(0, context, executionContext);
|
|
|
|
for(typename NodeSet<string_type, string_adaptor>::const_iterator n = ns.begin(), end = ns.end(); n != end; ++n)
|
2005-08-23 21:19:17 +02:00
|
|
|
sum += nodeNumberValue<string_type, string_adaptor>(*n);
|
2005-08-18 15:18:33 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(sum);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class SumFn
|
|
|
|
|
|
|
|
// number floor(number)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class FloorFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
FloorFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(std::floor(baseT::argAsNumber(0, context, executionContext)));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class FloorFn
|
|
|
|
|
|
|
|
// number ceiling(number)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class CeilingFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
CeilingFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(std::ceil(baseT::argAsNumber(0, context, executionContext)));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class CeilingFn
|
|
|
|
|
|
|
|
// number round(number)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
|
|
|
class RoundFn : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
typedef XPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2005-08-18 15:18:33 +02:00
|
|
|
RoundFn(const std::vector<XPathExpressionPtr<string_type, string_adaptor> >& args) : XPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
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
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
2005-08-18 15:18:33 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2005-08-18 15:18:33 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(roundNumber(baseT::argAsNumber(0, context, executionContext)));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
}; // class RoundFn
|
|
|
|
|
2005-08-22 17:04:27 +02:00
|
|
|
} // namespace impl
|
2005-08-04 22:42:30 +02:00
|
|
|
} // namespace XPath
|
|
|
|
} // namespace Arabica
|
|
|
|
|
|
|
|
#endif
|