mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-17 18:12:04 +01:00
still chipping away at function-available
This commit is contained in:
parent
fb380c8e08
commit
cbc3f6e8d6
7 changed files with 69 additions and 53 deletions
|
@ -15,7 +15,9 @@ namespace impl
|
|||
template<class function_type, class string_type, class string_adaptor>
|
||||
XPathFunction<string_type, string_adaptor>* CreateFn(const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs) { return new function_type(argExprs); }
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
} // namespace impl
|
||||
|
||||
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
||||
class StandardXPathFunctionResolver
|
||||
{
|
||||
public:
|
||||
|
@ -29,10 +31,13 @@ public:
|
|||
return standardFunction(namespace_uri, name, argExprs);
|
||||
} // resolveFuncton
|
||||
|
||||
virtual bool hasFunction(const string_type& namespace_uri,
|
||||
const string_type& name) const
|
||||
virtual std::vector<std::pair<string_type, string_type> > validNames() const
|
||||
{
|
||||
return findFunction(namespace_uri, name);
|
||||
std::vector<std::pair<string_type, string_type> > names;
|
||||
for(const NamedFunction* fn = FunctionLookupTable; fn->name != 0; ++fn)
|
||||
names.push_back(std::make_pair(string_adaptor::empty_string(),
|
||||
string_adaptor::construct_from_utf8(fn->name)));
|
||||
return names;
|
||||
} // hasFunction
|
||||
|
||||
static XPathFunction<string_type, string_adaptor>*
|
||||
|
@ -69,37 +74,40 @@ template<class string_type, class string_adaptor>
|
|||
const typename StandardXPathFunctionResolver<string_type, string_adaptor>::NamedFunction
|
||||
StandardXPathFunctionResolver<string_type, string_adaptor>::FunctionLookupTable[] =
|
||||
{ // node-set functions
|
||||
{ "position", CreateFn<PositionFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "last", CreateFn<LastFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "count", CreateFn<CountFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "local-name", CreateFn<LocalNameFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "namespace-uri", CreateFn<NamespaceURIFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "name", CreateFn<NameFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "position", impl::CreateFn<impl::PositionFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "last", impl::CreateFn<impl::LastFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "count", impl::CreateFn<impl::CountFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "local-name", impl::CreateFn<impl::LocalNameFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "namespace-uri", impl::CreateFn<impl::NamespaceURIFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{ "name", impl::CreateFn<impl::NameFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
// string functions
|
||||
{"string", CreateFn<StringFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"concat", CreateFn<ConcatFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"starts-with", CreateFn<StartsWithFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"contains", CreateFn<ContainsFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"substring-before", CreateFn<SubstringBeforeFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"substring-after", CreateFn<SubstringAfterFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"substring", CreateFn<SubstringFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"string-length", CreateFn<StringLengthFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"normalize-space", CreateFn<NormalizeSpaceFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"translate", CreateFn<TranslateFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"string", impl::CreateFn<impl::StringFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"concat", impl::CreateFn<impl::ConcatFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"starts-with", impl::CreateFn<impl::StartsWithFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"contains", impl::CreateFn<impl::ContainsFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"substring-before", impl::CreateFn<impl::SubstringBeforeFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"substring-after", impl::CreateFn<impl::SubstringAfterFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"substring", impl::CreateFn<impl::SubstringFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"string-length", impl::CreateFn<impl::StringLengthFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"normalize-space", impl::CreateFn<impl::NormalizeSpaceFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"translate", impl::CreateFn<impl::TranslateFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
// boolean functions
|
||||
{"boolean", CreateFn<BooleanFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"not", CreateFn<NotFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"true", CreateFn<TrueFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"false", CreateFn<FalseFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"boolean", impl::CreateFn<impl::BooleanFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"not", impl::CreateFn<impl::NotFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"true", impl::CreateFn<impl::TrueFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"false", impl::CreateFn<impl::FalseFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
// number functions
|
||||
{"number", CreateFn<NumberFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"sum", CreateFn<SumFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"floor", CreateFn<FloorFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"ceiling", CreateFn<CeilingFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"round", CreateFn<RoundFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"number", impl::CreateFn<impl::NumberFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"sum", impl::CreateFn<impl::SumFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"floor", impl::CreateFn<impl::FloorFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"ceiling", impl::CreateFn<impl::CeilingFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{"round", impl::CreateFn<impl::RoundFn<string_type, string_adaptor>, string_type, string_adaptor> },
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
namespace impl
|
||||
{
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
class FunctionHolder : public XPathExpression_impl<string_type, string_adaptor>
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
const string_type& name,
|
||||
const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs) const = 0;
|
||||
|
||||
virtual bool hasFunction(const string_type& namespace_uri, const string_type& name) const = 0;
|
||||
virtual std::vector<std::pair<string_type, string_type> > validNames() const = 0;
|
||||
}; // class FunctionResolver
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
|
@ -59,10 +59,11 @@ public:
|
|||
throw UndefinedFunctionException(string_adaptor().asStdString(error));
|
||||
} // resolveVariable
|
||||
|
||||
virtual bool hasFunction(const string_type&, const string_type&) const
|
||||
virtual std::vector<std::pair<string_type, string_type> > validNames() const
|
||||
{
|
||||
return false;
|
||||
} // hasFunction
|
||||
const std::vector<std::pair<string_type, string_type> > none;
|
||||
return none;
|
||||
} // validNames
|
||||
}; // NullFunctionResolver
|
||||
|
||||
} // namespace XPath
|
||||
|
|
|
@ -177,6 +177,7 @@ private:
|
|||
if(name == "key")
|
||||
return new KeyFunction(stylesheet_.keys(), parser_.inScopeNamespaces(), argExprs);
|
||||
// format-number
|
||||
// current
|
||||
if((name == "current") && (current_allowed_))
|
||||
return new CurrentFunction(argExprs);
|
||||
// unparsed-entity-uri
|
||||
|
@ -190,16 +191,24 @@ private:
|
|||
// element-available
|
||||
// function-available
|
||||
if(name == "function-available")
|
||||
return new FunctionAvailableFunction(argExprs, xpath_);
|
||||
|
||||
return new FunctionAvailableFunction(validNames(), parser_.inScopeNamespaces(), argExprs);
|
||||
|
||||
return 0;
|
||||
} // resolveFunction
|
||||
|
||||
virtual bool hasFunction(const std::string& /* namespace_uri */,
|
||||
const std::string& /* name */) const
|
||||
virtual std::vector<std::pair<std::string, std::string> > validNames() const
|
||||
{
|
||||
return false;
|
||||
} // hasFunction
|
||||
static const char* functionNames[] = { "document", "key", /* format-number, */ "current",
|
||||
/* unparsed-entity-uri, */ "generate-id", "system-property",
|
||||
/* element-available, */ "function-available", 0 };
|
||||
|
||||
std::vector<std::pair<std::string,std::string> > names;
|
||||
|
||||
for(int i = 0; functionNames[i] != 0; ++i)
|
||||
names.push_back(std::make_pair("", functionNames[i]));
|
||||
|
||||
return names;
|
||||
} // validNames
|
||||
|
||||
// NamespaceContext
|
||||
virtual std::string namespaceURI(const std::string& prefix) const
|
||||
|
|
|
@ -223,10 +223,12 @@ class FunctionAvailableFunction : public Arabica::XPath::BooleanXPathFunction<st
|
|||
{
|
||||
typedef Arabica::XPath::BooleanXPathFunction<std::string> baseT;
|
||||
public:
|
||||
FunctionAvailableFunction(const std::vector<Arabica::XPath::XPathExpression<std::string> >& args,
|
||||
const Arabica::XPath::XPath<std::string>& xpath) :
|
||||
FunctionAvailableFunction(const std::vector<std::pair<std::string, std::string> >& names,
|
||||
const std::map<std::string, std::string>& inscopeNamespaces,
|
||||
const std::vector<Arabica::XPath::XPathExpression<std::string> >& args) :
|
||||
Arabica::XPath::BooleanXPathFunction<std::string>(1, 1, args),
|
||||
xpath_(xpath)
|
||||
functionNames_(names),
|
||||
namespaces_(inscopeNamespaces)
|
||||
{
|
||||
} // FunctionAvailableFunction
|
||||
|
||||
|
@ -235,13 +237,15 @@ protected:
|
|||
const Arabica::XPath::ExecutionContext<std::string>& executionContext) const
|
||||
{
|
||||
const std::string functionName = baseT::argAsString(0, context, executionContext);
|
||||
const std::vector<Arabica::XPath::XPathExpression<std::string> > dummyArgs;
|
||||
|
||||
return false;
|
||||
} // doEvaluate
|
||||
|
||||
private:
|
||||
const Arabica::XPath::XPath<std::string>& xpath_;
|
||||
const std::vector<std::pair<std::string, std::string> > functionNames_;
|
||||
const std::map<std::string, std::string> namespaces_;
|
||||
|
||||
static Arabica::XPath::StandardXPathFunctionResolver<std::string> xpathStandardFunctionResolver;
|
||||
}; // class FunctionAvailableFunction
|
||||
|
||||
} // namespace XSLT
|
||||
|
|
|
@ -77,7 +77,7 @@ public:
|
|||
}; // TestFunction
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
class TestFunctionResolver : public Arabica::XPath::FunctionResolver<string_type, string_adaptor>
|
||||
class TestFunctionResolver : public Arabica::XPath::NullFunctionResolver<string_type, string_adaptor>
|
||||
{
|
||||
//typedef string_adaptorstring_adaptor;
|
||||
public:
|
||||
|
@ -90,8 +90,6 @@ public:
|
|||
return new TestFunction<string_type, string_adaptor>(argExprs);
|
||||
return 0;
|
||||
} // resolveFunction
|
||||
|
||||
virtual bool hasFunction(const string_type&, const string_type&) const { return false; }
|
||||
}; // class TestFunctionResolver
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
}; // TestKeyFunction
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
class TestIdKeyFunctionResolver : public Arabica::XPath::FunctionResolver<string_type, string_adaptor>
|
||||
class TestIdKeyFunctionResolver : public Arabica::XPath::NullFunctionResolver<string_type, string_adaptor>
|
||||
{
|
||||
//typedef string_adaptorstring_adaptor;
|
||||
public:
|
||||
|
@ -61,8 +61,6 @@ public:
|
|||
return new TestKeyFunction<string_type, string_adaptor>(argExprs);
|
||||
return 0;
|
||||
} // resolveFunction
|
||||
|
||||
virtual bool hasFunction(const string_type&, const string_type&) const { return false; }
|
||||
}; // class TestFunctionResolver
|
||||
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <XPath/XPath.hpp>
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
class TrueFunctionResolver : public Arabica::XPath::FunctionResolver<string_type, string_adaptor>
|
||||
class TrueFunctionResolver : public Arabica::XPath::NullFunctionResolver<string_type, string_adaptor>
|
||||
{
|
||||
//typedef string_adaptorstring_adaptor;
|
||||
public:
|
||||
|
@ -21,8 +21,6 @@ public:
|
|||
return new Arabica::XPath::impl::TrueFn<string_type, string_adaptor>(argExprs);
|
||||
return 0;
|
||||
} // resolveFunction
|
||||
|
||||
virtual bool hasFunction(const string_type&, const string_type&) const { return false; }
|
||||
}; // class TrueFunctionResolver
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
|
|
Loading…
Reference in a new issue