still chipping away at function-available

This commit is contained in:
Jez Higgins 2010-02-20 21:56:47 +00:00
parent fb380c8e08
commit cbc3f6e8d6
7 changed files with 69 additions and 53 deletions

View file

@ -15,7 +15,9 @@ namespace impl
template<class function_type, class string_type, class string_adaptor> 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); } 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 class StandardXPathFunctionResolver
{ {
public: public:
@ -29,10 +31,13 @@ public:
return standardFunction(namespace_uri, name, argExprs); return standardFunction(namespace_uri, name, argExprs);
} // resolveFuncton } // resolveFuncton
virtual bool hasFunction(const string_type& namespace_uri, virtual std::vector<std::pair<string_type, string_type> > validNames() const
const string_type& name) 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 } // hasFunction
static XPathFunction<string_type, string_adaptor>* 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 const typename StandardXPathFunctionResolver<string_type, string_adaptor>::NamedFunction
StandardXPathFunctionResolver<string_type, string_adaptor>::FunctionLookupTable[] = StandardXPathFunctionResolver<string_type, string_adaptor>::FunctionLookupTable[] =
{ // node-set functions { // node-set functions
{ "position", CreateFn<PositionFn<string_type, string_adaptor>, string_type, string_adaptor> }, { "position", impl::CreateFn<impl::PositionFn<string_type, string_adaptor>, string_type, string_adaptor> },
{ "last", CreateFn<LastFn<string_type, string_adaptor>, string_type, string_adaptor> }, { "last", impl::CreateFn<impl::LastFn<string_type, string_adaptor>, string_type, string_adaptor> },
{ "count", CreateFn<CountFn<string_type, string_adaptor>, string_type, string_adaptor> }, { "count", impl::CreateFn<impl::CountFn<string_type, string_adaptor>, string_type, string_adaptor> },
{ "local-name", CreateFn<LocalNameFn<string_type, string_adaptor>, string_type, string_adaptor> }, { "local-name", impl::CreateFn<impl::LocalNameFn<string_type, string_adaptor>, string_type, string_adaptor> },
{ "namespace-uri", CreateFn<NamespaceURIFn<string_type, string_adaptor>, string_type, string_adaptor> }, { "namespace-uri", impl::CreateFn<impl::NamespaceURIFn<string_type, string_adaptor>, string_type, string_adaptor> },
{ "name", CreateFn<NameFn<string_type, string_adaptor>, string_type, string_adaptor> }, { "name", impl::CreateFn<impl::NameFn<string_type, string_adaptor>, string_type, string_adaptor> },
// string functions // string functions
{"string", CreateFn<StringFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"string", impl::CreateFn<impl::StringFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"concat", CreateFn<ConcatFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"concat", impl::CreateFn<impl::ConcatFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"starts-with", CreateFn<StartsWithFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"starts-with", impl::CreateFn<impl::StartsWithFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"contains", CreateFn<ContainsFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"contains", impl::CreateFn<impl::ContainsFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"substring-before", CreateFn<SubstringBeforeFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"substring-before", impl::CreateFn<impl::SubstringBeforeFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"substring-after", CreateFn<SubstringAfterFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"substring-after", impl::CreateFn<impl::SubstringAfterFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"substring", CreateFn<SubstringFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"substring", impl::CreateFn<impl::SubstringFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"string-length", CreateFn<StringLengthFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"string-length", impl::CreateFn<impl::StringLengthFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"normalize-space", CreateFn<NormalizeSpaceFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"normalize-space", impl::CreateFn<impl::NormalizeSpaceFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"translate", CreateFn<TranslateFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"translate", impl::CreateFn<impl::TranslateFn<string_type, string_adaptor>, string_type, string_adaptor> },
// boolean functions // boolean functions
{"boolean", CreateFn<BooleanFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"boolean", impl::CreateFn<impl::BooleanFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"not", CreateFn<NotFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"not", impl::CreateFn<impl::NotFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"true", CreateFn<TrueFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"true", impl::CreateFn<impl::TrueFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"false", CreateFn<FalseFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"false", impl::CreateFn<impl::FalseFn<string_type, string_adaptor>, string_type, string_adaptor> },
// number functions // number functions
{"number", CreateFn<NumberFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"number", impl::CreateFn<impl::NumberFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"sum", CreateFn<SumFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"sum", impl::CreateFn<impl::SumFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"floor", CreateFn<FloorFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"floor", impl::CreateFn<impl::FloorFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"ceiling", CreateFn<CeilingFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"ceiling", impl::CreateFn<impl::CeilingFn<string_type, string_adaptor>, string_type, string_adaptor> },
{"round", CreateFn<RoundFn<string_type, string_adaptor>, string_type, string_adaptor> }, {"round", impl::CreateFn<impl::RoundFn<string_type, string_adaptor>, string_type, string_adaptor> },
{0, 0} {0, 0}
}; };
namespace impl
{
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
class FunctionHolder : public XPathExpression_impl<string_type, string_adaptor> class FunctionHolder : public XPathExpression_impl<string_type, string_adaptor>
{ {

View file

@ -26,7 +26,7 @@ public:
const string_type& name, const string_type& name,
const std::vector<XPathExpression<string_type, string_adaptor> >& argExprs) const = 0; 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 }; // class FunctionResolver
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
@ -59,10 +59,11 @@ public:
throw UndefinedFunctionException(string_adaptor().asStdString(error)); throw UndefinedFunctionException(string_adaptor().asStdString(error));
} // resolveVariable } // resolveVariable
virtual bool hasFunction(const string_type&, const string_type&) const virtual std::vector<std::pair<string_type, string_type> > validNames() const
{ {
return false; const std::vector<std::pair<string_type, string_type> > none;
} // hasFunction return none;
} // validNames
}; // NullFunctionResolver }; // NullFunctionResolver
} // namespace XPath } // namespace XPath

View file

@ -177,6 +177,7 @@ private:
if(name == "key") if(name == "key")
return new KeyFunction(stylesheet_.keys(), parser_.inScopeNamespaces(), argExprs); return new KeyFunction(stylesheet_.keys(), parser_.inScopeNamespaces(), argExprs);
// format-number // format-number
// current
if((name == "current") && (current_allowed_)) if((name == "current") && (current_allowed_))
return new CurrentFunction(argExprs); return new CurrentFunction(argExprs);
// unparsed-entity-uri // unparsed-entity-uri
@ -190,16 +191,24 @@ private:
// element-available // element-available
// function-available // function-available
if(name == "function-available") if(name == "function-available")
return new FunctionAvailableFunction(argExprs, xpath_); return new FunctionAvailableFunction(validNames(), parser_.inScopeNamespaces(), argExprs);
return 0; return 0;
} // resolveFunction } // resolveFunction
virtual bool hasFunction(const std::string& /* namespace_uri */, virtual std::vector<std::pair<std::string, std::string> > validNames() const
const std::string& /* name */) const
{ {
return false; static const char* functionNames[] = { "document", "key", /* format-number, */ "current",
} // hasFunction /* 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 // NamespaceContext
virtual std::string namespaceURI(const std::string& prefix) const virtual std::string namespaceURI(const std::string& prefix) const

View file

@ -223,10 +223,12 @@ class FunctionAvailableFunction : public Arabica::XPath::BooleanXPathFunction<st
{ {
typedef Arabica::XPath::BooleanXPathFunction<std::string> baseT; typedef Arabica::XPath::BooleanXPathFunction<std::string> baseT;
public: public:
FunctionAvailableFunction(const std::vector<Arabica::XPath::XPathExpression<std::string> >& args, FunctionAvailableFunction(const std::vector<std::pair<std::string, std::string> >& names,
const Arabica::XPath::XPath<std::string>& xpath) : 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), Arabica::XPath::BooleanXPathFunction<std::string>(1, 1, args),
xpath_(xpath) functionNames_(names),
namespaces_(inscopeNamespaces)
{ {
} // FunctionAvailableFunction } // FunctionAvailableFunction
@ -235,13 +237,15 @@ protected:
const Arabica::XPath::ExecutionContext<std::string>& executionContext) const const Arabica::XPath::ExecutionContext<std::string>& executionContext) const
{ {
const std::string functionName = baseT::argAsString(0, context, executionContext); const std::string functionName = baseT::argAsString(0, context, executionContext);
const std::vector<Arabica::XPath::XPathExpression<std::string> > dummyArgs;
return false; return false;
} // doEvaluate } // doEvaluate
private: 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 }; // class FunctionAvailableFunction
} // namespace XSLT } // namespace XSLT

View file

@ -77,7 +77,7 @@ public:
}; // TestFunction }; // TestFunction
template<class string_type, class string_adaptor> 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; //typedef string_adaptorstring_adaptor;
public: public:
@ -90,8 +90,6 @@ public:
return new TestFunction<string_type, string_adaptor>(argExprs); return new TestFunction<string_type, string_adaptor>(argExprs);
return 0; return 0;
} // resolveFunction } // resolveFunction
virtual bool hasFunction(const string_type&, const string_type&) const { return false; }
}; // class TestFunctionResolver }; // class TestFunctionResolver
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>

View file

@ -46,7 +46,7 @@ public:
}; // TestKeyFunction }; // TestKeyFunction
template<class string_type, class string_adaptor> 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; //typedef string_adaptorstring_adaptor;
public: public:
@ -61,8 +61,6 @@ public:
return new TestKeyFunction<string_type, string_adaptor>(argExprs); return new TestKeyFunction<string_type, string_adaptor>(argExprs);
return 0; return 0;
} // resolveFunction } // resolveFunction
virtual bool hasFunction(const string_type&, const string_type&) const { return false; }
}; // class TestFunctionResolver }; // class TestFunctionResolver

View file

@ -7,7 +7,7 @@
#include <XPath/XPath.hpp> #include <XPath/XPath.hpp>
template<class string_type, class string_adaptor> 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; //typedef string_adaptorstring_adaptor;
public: public:
@ -21,8 +21,6 @@ public:
return new Arabica::XPath::impl::TrueFn<string_type, string_adaptor>(argExprs); return new Arabica::XPath::impl::TrueFn<string_type, string_adaptor>(argExprs);
return 0; return 0;
} // resolveFunction } // resolveFunction
virtual bool hasFunction(const string_type&, const string_type&) const { return false; }
}; // class TrueFunctionResolver }; // class TrueFunctionResolver
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>