#ifndef ARABICA_XSLT_FUNCTIONS_HPP #define ARABICA_XSLT_FUNCTIONS_HPP #include #include namespace Arabica { namespace XSLT { // node-set document(object, node-set?) class DocumentFunction : public Arabica::XPath::XPathFunction { typedef Arabica::XPath::XPathFunction baseT; public: DocumentFunction(const std::string& currentBase, const std::vector >& args) : Arabica::XPath::XPathFunction(1, 2, args), baseURI_(currentBase) { } virtual Arabica::XPath::ValueType type() const { return Arabica::XPath::NODE_SET; } virtual Arabica::XPath::XPathValue_impl* evaluate(const DOM::Node& context, const Arabica::XPath::ExecutionContext& executionContext) const { Arabica::XPath::NodeSet nodes; Arabica::XPath::XPathValuePtr a1 = arg(0, context, executionContext); if(a1->type() != Arabica::XPath::NODE_SET) load_document(a1->asString(), nodes); else throw Arabica::XPath::UnsupportedException("node-set arg version of document()"); return new Arabica::XPath::NodeSetValue(nodes); } // evaluate private: void load_document(const std::string& location, Arabica::XPath::NodeSet& nodes) const { SAX2DOM::Parser domParser; SAX::CatchErrorHandler eh; domParser.setErrorHandler(eh); Arabica::io::URI base(baseURI_); Arabica::io::URI absolute(base, location); SAX::InputSource is(absolute.as_string()); domParser.parse(is); if(!eh.errorsReported()) nodes.push_back(domParser.getDocument()); else std::cerr << eh.errors() << std::endl; } // load_document std::string baseURI_; }; // DocumentFunction // node-set key(string, object) // string format-number(number, string, string?) // node-set current() class CurrentFunction : public Arabica::XPath::XPathFunction { typedef Arabica::XPath::XPathFunction baseT; public: CurrentFunction(const std::vector >& args) : Arabica::XPath::XPathFunction(0, 0, args) { } virtual Arabica::XPath::ValueType type() const { return Arabica::XPath::NODE_SET; } virtual Arabica::XPath::XPathValue_impl* evaluate(const DOM::Node& context, const Arabica::XPath::ExecutionContext& executionContext) const { Arabica::XPath::NodeSet set; set.push_back(executionContext.currentNode()); return new Arabica::XPath::NodeSetValue(set); } // evaluate }; // CurrentFunction // string unparsed-entity-uri(string) // string generate-id(node-set?) // object system-property(string) class SystemPropertyFunction : public Arabica::XPath::XPathFunction { typedef Arabica::XPath::XPathFunction baseT; public: SystemPropertyFunction (const std::vector >& args) : Arabica::XPath::XPathFunction(1, 1, args) { } virtual Arabica::XPath::ValueType type() const { return Arabica::XPath::STRING; } virtual Arabica::XPath::XPathValue_impl* evaluate(const DOM::Node& context, const Arabica::XPath::ExecutionContext& executionContext) const { std::string property = baseT::argAsString(0, context, executionContext); std::string result; if(property == "xsl:version") result = "1.0"; else if(property == "xsl:vendor") result = "Jez Higgins, Jez UK Ltd"; else if(property == "xsl:vendor-url") result = "http://www.jezuk.co.uk/arabica"; return new Arabica::XPath::StringValue(result); } // evaluate }; // SystemPropertyFunction // boolean element-available(string) // boolean function-available(string) } // namespace XSLT } // namespace Arabica #endif // ARABICA_XSLT_FUNCTIONS_HPP