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:
|
2007-10-25 22:42:00 +02:00
|
|
|
XPathFunction(int minArgs, int maxArgs, const std::vector<XPathExpression<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() { }
|
|
|
|
|
2007-12-19 00:03:16 +01:00
|
|
|
virtual ValueType type() const = 0;
|
|
|
|
|
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-10-22 19:42:50 +02:00
|
|
|
XPathValue<string_type, string_adaptor> arg(size_t index,
|
2007-09-08 01:52:30 +02:00
|
|
|
const DOM::Node<string_type, string_adaptor>& context,
|
2007-07-19 19:01:31 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
|
|
|
{
|
2007-10-25 22:42:00 +02:00
|
|
|
return args_[index].evaluate(context, executionContext);
|
2009-07-13 09:24:52 +02:00
|
|
|
} // arg
|
2007-07-19 19:01:31 +02:00
|
|
|
|
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
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return args_[index].evaluateAsBool(context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // 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
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return args_[index].evaluateAsNumber(context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // 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
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return args_[index].evaluateAsString(context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // 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
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return args_[index].evaluateAsNodeSet(context, executionContext);
|
2005-08-04 22:42:30 +02:00
|
|
|
} // argAsNodeSet
|
|
|
|
|
|
|
|
private:
|
2007-10-25 22:42:00 +02:00
|
|
|
const std::vector<XPathExpression<string_type, string_adaptor> > args_;
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class XPathFunction
|
|
|
|
|
2009-07-13 10:13:11 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
|
|
|
class BooleanXPathFunction : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
BooleanXPathFunction(int minArgs, int maxArgs, const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-31 18:44:54 +02:00
|
|
|
XPathFunction<string_type, string_adaptor>(minArgs, maxArgs, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
virtual ValueType type() const { return BOOL; }
|
2007-12-19 00:03:16 +01: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
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return new BoolValue<string_type, string_adaptor>(doEvaluate(context, executionContext));
|
2005-08-04 22:42:30 +02:00
|
|
|
} // evaluate
|
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual bool doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
|
2009-07-13 10:13:11 +02:00
|
|
|
}; // class BooleanXPathFunction
|
2009-07-13 09:24:52 +02:00
|
|
|
|
2009-07-13 10:13:11 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
|
|
|
class NumericXPathFunction : public XPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
NumericXPathFunction(int minArgs, int maxArgs, const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-31 18:44:54 +02:00
|
|
|
XPathFunction<string_type, string_adaptor>(minArgs, maxArgs, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-12-19 00:03:16 +01:00
|
|
|
virtual ValueType type() const { return NUMBER; }
|
|
|
|
|
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
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return new NumericValue<string_type, string_adaptor>(doEvaluate(context, executionContext));
|
|
|
|
} // evaluate
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
|
2009-07-13 10:13:11 +02:00
|
|
|
}; // class NumericXPathFunction
|
2009-07-13 09:24:52 +02:00
|
|
|
|
2009-07-13 10:13:11 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
|
|
|
class StringXPathFunction : public XPathFunction<string_type, string_adaptor>
|
2009-07-13 09:47:46 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction(int minArgs, int maxArgs, const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-31 18:44:54 +02:00
|
|
|
XPathFunction<string_type, string_adaptor>(minArgs, maxArgs, args) { }
|
2009-07-13 09:47:46 +02:00
|
|
|
|
|
|
|
virtual ValueType type() const { return STRING; }
|
|
|
|
|
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
|
|
|
{
|
|
|
|
return new StringValue<string_type, string_adaptor>(doEvaluate(context, executionContext));
|
|
|
|
} // evaluate
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
|
2009-07-13 10:13:11 +02:00
|
|
|
}; // class StringXPathFunction
|
|
|
|
|
2009-07-13 10:24:03 +02:00
|
|
|
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
|
|
|
class NodeSetXPathFunction : public XPathFunction<string_type, string_adaptor>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NodeSetXPathFunction(int minArgs, int maxArgs, const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-31 18:44:54 +02:00
|
|
|
XPathFunction<string_type, string_adaptor>(minArgs, maxArgs, args) { }
|
2009-07-13 10:24:03 +02:00
|
|
|
|
|
|
|
virtual ValueType type() const { return NODE_SET; }
|
|
|
|
|
|
|
|
virtual XPathValue_impl<string_type, string_adaptor>* evaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
|
|
|
{
|
|
|
|
return new NodeSetValue<string_type, string_adaptor>(doEvaluate(context, executionContext));
|
|
|
|
} // evaluate
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual NodeSet<string_type, string_adaptor> doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const = 0;
|
|
|
|
}; // class NodeSetXPathFunction
|
|
|
|
|
2009-07-13 10:13:11 +02:00
|
|
|
namespace impl
|
|
|
|
{
|
2009-07-13 09:47:46 +02:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
////////////////////////////////
|
|
|
|
// node-set functions
|
|
|
|
// number last()
|
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class LastFn : public NumericXPathFunction<string_type, string_adaptor>
|
2009-07-13 09:24:52 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
LastFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2009-07-13 09:24:52 +02:00
|
|
|
|
|
|
|
protected:
|
2010-01-10 19:47:09 +01:00
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
|
2009-07-13 09:24:52 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
|
|
|
{
|
|
|
|
return executionContext.last();
|
|
|
|
} // evaluate
|
|
|
|
}; // class LastFn
|
|
|
|
|
|
|
|
// number position()
|
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class PositionFn : public NumericXPathFunction<string_type, string_adaptor>
|
2009-07-13 09:24:52 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
PositionFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2009-07-13 09:24:52 +02:00
|
|
|
|
|
|
|
protected:
|
2010-01-10 19:47:09 +01:00
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
|
2009-07-13 09:24:52 +02:00
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
|
|
|
{
|
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class CountFn : public NumericXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef NumericXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
CountFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2016-04-03 09:48:33 +02:00
|
|
|
return static_cast<double>(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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class LocalNameFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
LocalNameFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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-11-10 23:23:36 +01:00
|
|
|
case NAMESPACE_NODE_TYPE:
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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 ...
|
2009-07-13 09:47:46 +02:00
|
|
|
return string_adaptor::empty_string();
|
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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class NamespaceURIFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
NamespaceURIFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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:
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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 ...
|
2009-07-13 09:47:46 +02:00
|
|
|
return string_adaptor::empty_string();
|
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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class NameFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
NameFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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:
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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 ...
|
2009-07-13 09:47:46 +02:00
|
|
|
return string_adaptor::empty_string();
|
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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class StringFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
StringFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:47:46 +02:00
|
|
|
return (baseT::argCount() > 0) ? baseT::argAsString(0, context, executionContext) :
|
|
|
|
nodeStringValue<string_type, string_adaptor>(context);
|
|
|
|
} // doEvaluate
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class StringFn
|
|
|
|
|
|
|
|
// string concat(string, string, string*)
|
2005-08-18 13:32:29 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class ConcatFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
ConcatFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(2, -1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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));
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class StartsWithFn : public BooleanXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef BooleanXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
StartsWithFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : BooleanXPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual bool doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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))
|
2009-07-13 09:24:52 +02:00
|
|
|
return 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)
|
2009-07-13 09:24:52 +02:00
|
|
|
return false;
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class ContainsFn : public BooleanXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef BooleanXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
ContainsFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : BooleanXPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual bool doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return string_adaptor::find(baseT::argAsString(0, context, executionContext),
|
|
|
|
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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class SubstringBeforeFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
SubstringBeforeFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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())
|
2009-07-13 09:47:46 +02:00
|
|
|
return string_adaptor::empty_string();
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class SubstringAfterFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
SubstringAfterFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(2, 2, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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)))
|
2009-07-13 09:47:46 +02:00
|
|
|
return string_adaptor::empty_string();
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class SubstringFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
SubstringFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(2, 3, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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))
|
2009-07-13 09:47:46 +02:00
|
|
|
return string_adaptor::empty_string();
|
2007-07-19 19:01:31 +02:00
|
|
|
|
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)))
|
2009-07-13 09:47:46 +02:00
|
|
|
return string_adaptor::empty_string();
|
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)))
|
2016-04-03 09:48:33 +02:00
|
|
|
endAt = static_cast<double>(string_adaptor::length(value));
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class StringLengthFn : public NumericXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef NumericXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
StringLengthFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
virtual double doEvaluate(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);
|
2016-04-03 09:48:33 +02:00
|
|
|
return static_cast<double>(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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class NormalizeSpaceFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
NormalizeSpaceFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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);
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class TranslateFn : public StringXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef StringXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 09:47:46 +02:00
|
|
|
TranslateFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) :
|
2009-07-13 10:13:11 +02:00
|
|
|
StringXPathFunction<string_type, string_adaptor>(3, 3, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
protected:
|
|
|
|
virtual string_type doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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
|
|
|
|
2009-07-13 09:47:46 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class BooleanFn : public BooleanXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef BooleanXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
BooleanFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : BooleanXPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual bool doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return baseT::argAsBool(0, context, executionContext);
|
|
|
|
} // doEvaluate
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class BooleanFn
|
|
|
|
|
|
|
|
// boolean not(boolean)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class NotFn : public BooleanXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef BooleanXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
NotFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : BooleanXPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual bool doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return !baseT::argAsBool(0, context, executionContext);
|
|
|
|
} // doEvaluate
|
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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class TrueFn : public BooleanXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
TrueFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : BooleanXPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
2010-01-10 19:47:09 +01:00
|
|
|
virtual bool doEvaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return true;
|
|
|
|
} // doEvaluate
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // TrueFn
|
|
|
|
|
|
|
|
// boolean false()
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class FalseFn : public BooleanXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
FalseFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : BooleanXPathFunction<string_type, string_adaptor>(0, 0, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
2010-01-10 19:47:09 +01:00
|
|
|
virtual bool doEvaluate(const DOM::Node<string_type, string_adaptor>& /* context */,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& /* executionContext */) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class NumberFn : public NumericXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef NumericXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
NumberFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(0, 1, args) { }
|
2005-08-04 22:42:30 +02:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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();
|
2009-07-13 09:24:52 +02:00
|
|
|
return 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>
|
2009-07-13 10:13:11 +02:00
|
|
|
class SumFn : public NumericXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef NumericXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
SumFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
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);
|
2009-07-13 09:24:52 +02:00
|
|
|
return sum;
|
|
|
|
} // doEvaluate
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class SumFn
|
|
|
|
|
|
|
|
// number floor(number)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class FloorFn : public NumericXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef NumericXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
FloorFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2009-07-13 09:24:52 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return std::floor(baseT::argAsNumber(0, context, executionContext));
|
|
|
|
} // doEvaluate
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class FloorFn
|
|
|
|
|
|
|
|
// number ceiling(number)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class CeilingFn : public NumericXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef NumericXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
CeilingFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return std::ceil(baseT::argAsNumber(0, context, executionContext));
|
|
|
|
} // doEvaluate
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // class CeilingFn
|
|
|
|
|
|
|
|
// number round(number)
|
2005-08-18 15:18:33 +02:00
|
|
|
template<class string_type, class string_adaptor>
|
2009-07-13 10:13:11 +02:00
|
|
|
class RoundFn : public NumericXPathFunction<string_type, string_adaptor>
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 10:13:11 +02:00
|
|
|
typedef NumericXPathFunction<string_type, string_adaptor> baseT;
|
2005-08-04 22:42:30 +02:00
|
|
|
public:
|
2009-07-13 10:13:11 +02:00
|
|
|
RoundFn(const std::vector<XPathExpression<string_type, string_adaptor> >& args) : NumericXPathFunction<string_type, string_adaptor>(1, 1, args) { }
|
2007-12-19 00:03:16 +01:00
|
|
|
|
2009-07-13 09:24:52 +02:00
|
|
|
protected:
|
|
|
|
virtual double doEvaluate(const DOM::Node<string_type, string_adaptor>& context,
|
|
|
|
const ExecutionContext<string_type, string_adaptor>& executionContext) const
|
2005-08-04 22:42:30 +02:00
|
|
|
{
|
2009-07-13 09:24:52 +02:00
|
|
|
return roundNumber(baseT::argAsNumber(0, context, executionContext));
|
|
|
|
} // doEvaluate
|
2005-08-04 22:42:30 +02:00
|
|
|
}; // 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
|