arabica/XPath/impl/xpath_function.hpp

561 lines
26 KiB
C++
Raw Normal View History

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>
#include <XML/XMLCharacterClasses.h>
#include <XML/UnicodeCharacters.h>
#include "xpath_value.hpp"
#include "xpath_execution_context.hpp"
namespace Arabica
{
namespace XPath
{
2005-08-18 11:00:35 +02:00
template<class string_type, class string_adaptor>
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() { }
2005-08-18 11:00:35 +02:00
virtual XPathValue<string_type>* evaluate(const DOM::Node<string_type>& context,
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(); }
bool argAsBool(size_t index,
2005-08-18 11:00:35 +02:00
const DOM::Node<string_type>& context,
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,
2005-08-18 11:00:35 +02:00
const DOM::Node<string_type>& context,
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,
const DOM::Node<string_type>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
2005-08-04 22:42:30 +02:00
{
return args_[index]->evaluate(context, executionContext)->asString();
} // argAsString
2005-08-18 11:00:35 +02:00
NodeSet<string_type> argAsNodeSet(size_t index,
const DOM::Node<string_type>& context,
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
////////////////////////////////
// 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
2005-08-18 11:33:19 +02:00
virtual XPathValue<string_type>* evaluate(const DOM::Node<string_type>& context,
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
2005-08-18 11:33:19 +02:00
virtual XPathValue<string_type>* evaluate(const DOM::Node<string_type>& context,
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
2005-08-18 11:33:19 +02:00
virtual XPathValue<string_type>* evaluate(const DOM::Node<string_type>& context,
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
2005-08-18 11:33:19 +02:00
virtual XPathValue<string_type>* evaluate(const DOM::Node<string_type>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
2005-08-04 22:42:30 +02:00
{
2005-08-18 11:33:19 +02:00
DOM::Node<string_type> node;
if(baseT::argCount() == 0)
2005-08-04 22:42:30 +02:00
node = context;
else
{
2005-08-18 11:33:19 +02:00
NodeSet<string_type> 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());
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
2005-08-18 11:33:19 +02:00
virtual XPathValue<string_type>* evaluate(const DOM::Node<string_type>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
2005-08-04 22:42:30 +02:00
{
2005-08-18 11:33:19 +02:00
DOM::Node<string_type> node;
if(baseT::argCount() == 0)
2005-08-04 22:42:30 +02:00
node = context;
else
{
2005-08-18 11:33:19 +02:00
NodeSet<string_type> 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());
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
2005-08-18 11:33:19 +02:00
virtual XPathValue<string_type>* evaluate(const DOM::Node<string_type>& context,
const ExecutionContext<string_type, string_adaptor>& executionContext) const
2005-08-04 22:42:30 +02:00
{
2005-08-18 11:33:19 +02:00
DOM::Node<string_type> node;
if(baseT::argCount() == 0)
2005-08-04 22:42:30 +02:00
node = context;
else
{
2005-08-18 11:33:19 +02:00
NodeSet<string_type> 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.getNodeName());
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 11:00:35 +02:00
class StringFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
StringFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(0, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context));
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class StringFn
// string concat(string, string, string*)
2005-08-18 11:00:35 +02:00
class ConcatFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
ConcatFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(2, -1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
std::string s;
for(size_t a = 0, ae = argCount(); a < ae; ++a)
s.append(argAsString(a, context, executionContext));
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >(s);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // ConcatFn
// boolean starts-with(string, string)
2005-08-18 11:00:35 +02:00
class StartsWithFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
StartsWithFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(2, 2, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
std::string value = argAsString(0, context, executionContext);
std::string start = argAsString(1, context, executionContext);
if(value.length() < start.length())
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(false);
2005-08-04 22:42:30 +02:00
for(size_t i = 0, ie = start.length(); i < ie; ++i)
if(value[i] != start[i])
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(false);
2005-08-04 22:42:30 +02:00
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(true);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // StartsWithFn
// boolean contains(string, string)
2005-08-18 11:00:35 +02:00
class ContainsFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
ContainsFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(2, 2, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(argAsString(0, context, executionContext).find(argAsString(1, context, executionContext)) != std::string::npos);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class ContainsFn
// string substring-before(string, string)
2005-08-18 11:00:35 +02:00
class SubstringBeforeFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
SubstringBeforeFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(2, 2, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
std::string value = argAsString(0, context, executionContext);
size_t splitAt = value.find(argAsString(1, context, executionContext));
if(splitAt == std::string::npos)
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >("");
2005-08-04 22:42:30 +02:00
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >(value.substr(0, splitAt));
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class SubstringBeforeFn
// string substring-after(string, string)
2005-08-18 11:00:35 +02:00
class SubstringAfterFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
SubstringAfterFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(2, 2, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
std::string value = argAsString(0, context, executionContext);
std::string split = argAsString(1, context, executionContext);
size_t splitAt = value.find(split);
if((splitAt == std::string::npos) || ((splitAt + split.length()) >= value.length()))
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >("");
2005-08-04 22:42:30 +02:00
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >(value.substr(splitAt + split.length()));
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class SubstringAfterFn
// string substring(string, number, number?)
2005-08-18 11:00:35 +02:00
class SubstringFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
SubstringFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(2, 3, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
std::string value = argAsString(0, context, executionContext);
double startAt = roundNumber(argAsNumber(1, context, executionContext)) - 1;
double endAt = roundNumber((argCount() == 3 ? argAsNumber(2, context, executionContext) : Infinity)) + startAt;
2005-08-07 22:11:43 +02:00
if((endAt < 0) || (endAt < startAt) || (isNaN(endAt)))
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >("");
2005-08-04 22:42:30 +02:00
if(startAt < 0)
startAt = 0;
if((isInfinite(endAt)) || (endAt > value.length()))
endAt = value.length();
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >(value.substr(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 11:00:35 +02:00
class StringLengthFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
StringLengthFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(0, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
2005-08-17 09:01:27 +02:00
return new NumericValue<std::string, Arabica::default_string_adaptor<std::string> >(((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context)).length());
2005-08-04 22:42:30 +02:00
} // evaluate
}; // StringLengthFn
// string normalize-space(string?)
2005-08-18 11:00:35 +02:00
class NormalizeSpaceFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
NormalizeSpaceFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(0, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
std::string value = ((argCount() > 0) ? argAsString(0, context, executionContext) : nodeStringValue(context));
size_t i = 0, ie = value.length();
// string leading space
while((i != ie) && (XML::is_space(static_cast<wchar_t>(value[i]))))
++i;
size_t p = 0;
while(i != ie)
{
while((i != ie) && (!XML::is_space(static_cast<wchar_t>(value[i]))))
value[p++] = value[i++];
while((i != ie) && (XML::is_space(static_cast<wchar_t>(value[i]))))
++i;
if(i != ie)
value[p++] = Unicode<char>::SPACE;
} // while ...
if(p != ie)
value.resize(p);
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >(value);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class NormalizeSpaceFn
// string translate(string, string, string)
2005-08-18 11:00:35 +02:00
class TranslateFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
TranslateFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(3, 3, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
std::string str = argAsString(0, context, executionContext);
std::string from = argAsString(1, context, executionContext);
std::string to = argAsString(2, context, executionContext);
size_t p = 0;
for(size_t i = 0, ie = str.length(); i != ie; ++i)
{
size_t r = from.find(str[i]);
if(r == std::string::npos)
++p;
else if(r < to.length())
str[p++] = to[r];
} // for ...
if(p != str.length())
str.resize(p);
return new StringValue<std::string, Arabica::default_string_adaptor<std::string> >(str);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class TranslateFn
///////////////////////////////////////////////////////
// boolean functions
// boolean boolean(object)
2005-08-18 11:00:35 +02:00
class BooleanFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
BooleanFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(1, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(argAsBool(0, context, executionContext));
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class BooleanFn
// boolean not(boolean)
2005-08-18 11:00:35 +02:00
class NotFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
NotFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(1, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(!argAsBool(0, context, executionContext));
2005-08-04 22:42:30 +02:00
}
}; // class NotFn
// boolean true()
2005-08-18 11:00:35 +02:00
class TrueFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
TrueFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(0, 0, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(true);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // TrueFn
// boolean false()
2005-08-18 11:00:35 +02:00
class FalseFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
FalseFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(0, 0, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
return new BoolValue<std::string, Arabica::default_string_adaptor<std::string> >(false);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // FalseFn
// boolean lang(string)
/////////////////////////////////////////////////
// number functions
// number number(object?)
2005-08-18 11:00:35 +02:00
class NumberFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
NumberFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(0, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
double result = (argCount() > 0) ? argAsNumber(0, context, executionContext) :
StringValue<std::string, Arabica::default_string_adaptor<std::string> >(nodeStringValue(context)).asNumber();
2005-08-17 09:01:27 +02:00
return new NumericValue<std::string, Arabica::default_string_adaptor<std::string> >(result);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // NumberFn
// number sum(node-set)
2005-08-18 11:00:35 +02:00
class SumFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
SumFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(1, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
double sum = 0;
NodeSet<std::string> ns = argAsNodeSet(0, context, executionContext);
for(NodeSet<std::string>::const_iterator n = ns.begin(), end = ns.end(); n != end; ++n)
2005-08-04 22:42:30 +02:00
sum += nodeNumberValue(*n);
2005-08-17 09:01:27 +02:00
return new NumericValue<std::string, Arabica::default_string_adaptor<std::string> >(sum);
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class SumFn
// number floor(number)
2005-08-18 11:00:35 +02:00
class FloorFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
FloorFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(1, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
2005-08-17 09:01:27 +02:00
return new NumericValue<std::string, Arabica::default_string_adaptor<std::string> >(std::floor(argAsNumber(0, context, executionContext)));
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class FloorFn
// number ceiling(number)
2005-08-18 11:00:35 +02:00
class CeilingFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
CeilingFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(1, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
2005-08-17 09:01:27 +02:00
return new NumericValue<std::string, Arabica::default_string_adaptor<std::string> >(std::ceil(argAsNumber(0, context, executionContext)));
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class CeilingFn
// number round(number)
2005-08-18 11:00:35 +02:00
class RoundFn : public XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >
2005-08-04 22:42:30 +02:00
{
public:
2005-08-18 11:00:35 +02:00
RoundFn(const std::vector<XPathExpressionPtr<std::string, Arabica::default_string_adaptor<std::string> > >& args) : XPathFunction<std::string, Arabica::default_string_adaptor<std::string> >(1, 1, args) { }
2005-08-04 22:42:30 +02:00
virtual XPathValue<std::string>* evaluate(const DOM::Node<std::string>& context,
const ExecutionContext<std::string, Arabica::default_string_adaptor<std::string> >& executionContext) const
2005-08-04 22:42:30 +02:00
{
2005-08-17 09:01:27 +02:00
return new NumericValue<std::string, Arabica::default_string_adaptor<std::string> >(roundNumber(argAsNumber(0, context, executionContext)));
2005-08-04 22:42:30 +02:00
} // evaluate
}; // class RoundFn
} // namespace XPath
} // namespace Arabica
#endif