mirror of
https://github.com/jezhiggins/arabica
synced 2024-12-26 21:58:39 +01:00
First pass as parameterising the whole of the XSLT library on string_type is done
This commit is contained in:
parent
16b50bf4df
commit
39d85b29c6
47 changed files with 871 additions and 514 deletions
|
@ -11,7 +11,8 @@
|
|||
#include <DOM/io/Stream.hpp>
|
||||
#include <XSLT/XSLT.hpp>
|
||||
|
||||
Arabica::DOM::Document<std::string> buildDOM(const std::string& xml);
|
||||
Arabica::DOM::Document<std::wstring> buildDOM(const std::wstring& xml);
|
||||
typedef Arabica::default_string_adaptor<std::wstring> adaptor;
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
@ -23,12 +24,12 @@ int main(int argc, const char* argv[])
|
|||
return 0;
|
||||
} // if ...
|
||||
|
||||
Arabica::XSLT::StylesheetCompiler<std::string> compiler;
|
||||
std::ostringstream errors;
|
||||
Arabica::XSLT::StylesheetCompiler<std::wstring> compiler;
|
||||
std::wostringstream errors;
|
||||
try
|
||||
{
|
||||
Arabica::SAX::InputSource<std::string> source(argv[2]);
|
||||
std::auto_ptr<Arabica::XSLT::Stylesheet<std::string> > stylesheet = compiler.compile(source);
|
||||
Arabica::SAX::InputSource<std::wstring> source(adaptor::construct_from_utf8(argv[2]));
|
||||
std::auto_ptr<Arabica::XSLT::Stylesheet<std::wstring> > stylesheet = compiler.compile(source);
|
||||
if(stylesheet.get() == 0)
|
||||
{
|
||||
std::cerr << "Couldn't compile stylesheet: " << compiler.error() << std::endl;
|
||||
|
@ -37,7 +38,7 @@ int main(int argc, const char* argv[])
|
|||
|
||||
stylesheet->set_error_output(errors);
|
||||
|
||||
Arabica::DOM::Document<std::string> document = buildDOM(argv[1]);
|
||||
Arabica::DOM::Document<std::wstring> document = buildDOM(adaptor::construct_from_utf8(argv[1]));
|
||||
if(document == 0)
|
||||
{
|
||||
std::cerr << "Could not parse XML source" << std::endl;
|
||||
|
@ -54,7 +55,7 @@ int main(int argc, const char* argv[])
|
|||
|
||||
stylesheet->execute(document);
|
||||
|
||||
Arabica::DOM::Node<std::string> node = output.node();
|
||||
Arabica::DOM::Node<std::wstring> node = output.node();
|
||||
std::cout << node << std::endl;
|
||||
*/
|
||||
}
|
||||
|
@ -63,15 +64,15 @@ int main(int argc, const char* argv[])
|
|||
std::cerr << ex.what() << std::endl;
|
||||
} // catch
|
||||
|
||||
std::cerr << "\n\n" << errors.str() << std::endl;
|
||||
std::wcerr << "\n\n" << errors.str() << std::endl;
|
||||
|
||||
return 0;
|
||||
} // main
|
||||
|
||||
Arabica::DOM::Document<std::string> buildDOM(const std::string& filename)
|
||||
Arabica::DOM::Document<std::wstring> buildDOM(const std::wstring& filename)
|
||||
{
|
||||
Arabica::SAX::InputSource<std::string> is(filename);
|
||||
Arabica::SAX2DOM::Parser<std::string> parser;
|
||||
Arabica::SAX::InputSource<std::wstring> is(filename);
|
||||
Arabica::SAX2DOM::Parser<std::wstring> parser;
|
||||
parser.parse(is);
|
||||
|
||||
return parser.getDocument();
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
ns[*p] = namespaces_.getURI(*p);
|
||||
} // for ...
|
||||
ns[""] = namespaces_.getURI("");
|
||||
ns[string_adaptor::empty_string()] = namespaces_.getURI(string_adaptor::empty_string());
|
||||
return ns;
|
||||
} // inScopeNamespaces
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:apply-imports");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, StylesheetConstant<string_type, string_adaptor>::apply_imports);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace XSLT
|
|||
template<class stringT, class adaptorT>
|
||||
class ApplyTemplatesHandler : public SAX::DefaultHandler<stringT, adaptorT>
|
||||
{
|
||||
typedef StylesheetConstant<stringT, adaptorT> SC;
|
||||
|
||||
public:
|
||||
typedef stringT string_type;
|
||||
typedef adaptorT string_adaptor;
|
||||
|
@ -30,27 +32,27 @@ public:
|
|||
{
|
||||
if(applyTemplates_ == 0)
|
||||
{
|
||||
static const ValueRule rules[] = { { "select", false, 0, 0 },
|
||||
{ "mode", false, 0, 0 },
|
||||
{ 0, false, 0, 0} };
|
||||
static const ValueRule<string_type> rules[] = { { SC::select, false, 0, 0 },
|
||||
{ SC::mode, false, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0} };
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
|
||||
const string_type& select = attrs["select"];
|
||||
const string_type& select = attrs[SC::select];
|
||||
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> xpath;
|
||||
if(select != "")
|
||||
if(select != string_adaptor::empty_string())
|
||||
xpath = context_.xpath_expression(select);
|
||||
|
||||
string_type mode;
|
||||
if(attrs["mode"] != "")
|
||||
mode = context_.processInternalQName(attrs["mode"]).clarkName();
|
||||
if(attrs[SC::mode] != string_adaptor::empty_string())
|
||||
mode = context_.processInternalQName(attrs[SC::mode]).clarkName();
|
||||
applyTemplates_ = new ApplyTemplates<string_type, string_adaptor>(xpath, mode);
|
||||
|
||||
return;
|
||||
} // if(applyTemplates_ == 0)
|
||||
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI)
|
||||
{
|
||||
if(localName == "sort")
|
||||
if(localName == SC::sort)
|
||||
{
|
||||
|
||||
context_.push(0,
|
||||
|
@ -62,7 +64,7 @@ public:
|
|||
return;
|
||||
} // if(localName == "sort")
|
||||
|
||||
if(localName == "with-param")
|
||||
if(localName == SC::with_param)
|
||||
{
|
||||
context_.push(0,
|
||||
new WithParamHandler<string_type, string_adaptor>(context_, *applyTemplates_),
|
||||
|
@ -87,11 +89,11 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:apply-templates");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::apply_templates);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
CompilationContext<string_type, string_adaptor>& context_;
|
||||
CompilationContext<string_type>& context_;
|
||||
ApplyTemplates<string_type, string_adaptor>* applyTemplates_;
|
||||
}; // class ApplyTemplatesHandler
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
|
|||
class AttributeHandler : public ItemContainerHandler<Attribute<string_type, string_adaptor> >
|
||||
{
|
||||
typedef ItemContainerHandler<Attribute<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
AttributeHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
baseT(context)
|
||||
|
@ -25,18 +26,19 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "name", true, 0, 0 },
|
||||
{ "namespace", false, "", 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
|
||||
{ SC::namespace_, false, string_adaptor::empty_string(), 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
|
||||
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> name = baseT::context().xpath_attribute_value_template(attrs["name"]);
|
||||
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> name =
|
||||
baseT::context().xpath_attribute_value_template(attrs[SC::name]);
|
||||
|
||||
if(attrs["namespace"] == "")
|
||||
if(attrs[SC::namespace_] == string_adaptor::empty_string())
|
||||
return new Attribute<string_type, string_adaptor>(name, baseT::context().inScopeNamespaces());
|
||||
|
||||
return new Attribute<string_type, string_adaptor>(name, baseT::context().xpath_attribute_value_template(attrs["namespace"]));
|
||||
return new Attribute<string_type, string_adaptor>(name, baseT::context().xpath_attribute_value_template(attrs[SC::namespace_]));
|
||||
} // createContainer
|
||||
}; // class AttributeHandler
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace XSLT
|
|||
template<class stringT, class adaptorT>
|
||||
class CallTemplateHandler : public SAX::DefaultHandler<stringT, adaptorT>
|
||||
{
|
||||
typedef StylesheetConstant<stringT, adaptorT> SC;
|
||||
public:
|
||||
typedef stringT string_type;
|
||||
typedef adaptorT string_adaptor;
|
||||
|
@ -29,18 +30,18 @@ public:
|
|||
{
|
||||
if(callTemplate_ == 0)
|
||||
{
|
||||
static const ValueRule rules[] = { { "name", true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
|
||||
string_type name = context_.processInternalQName(attrs["name"]).clarkName();
|
||||
string_type name = context_.processInternalQName(attrs[SC::name]).clarkName();
|
||||
|
||||
callTemplate_ = new CallTemplate<string_type, string_adaptor>(name);
|
||||
return;
|
||||
} // if(callTemplate_ == 0)
|
||||
|
||||
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) && (localName == "with-param"))
|
||||
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI) && (localName == SC::with_param))
|
||||
{
|
||||
context_.push(0,
|
||||
new WithParamHandler<string_type, string_adaptor>(context_, *callTemplate_),
|
||||
|
|
|
@ -17,6 +17,7 @@ public:
|
|||
|
||||
private:
|
||||
typedef ItemContainerHandler<When<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
WhenHandler(Choose<string_type, string_adaptor>* choose,
|
||||
|
@ -31,9 +32,9 @@ public:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "test", true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
string_type test = gatherAttributes(qName, atts, rules)["test"];
|
||||
static const ValueRule<string_type> rules[] = { { SC::test, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
string_type test = gatherAttributes(qName, atts, rules)[SC::test];
|
||||
|
||||
return new When<string_type, string_adaptor>(baseT::context().xpath_expression(test));
|
||||
} // startElement
|
||||
|
@ -54,6 +55,7 @@ template<class string_type, class string_adaptor>
|
|||
class OtherwiseHandler : public ItemContainerHandler<Otherwise<string_type, string_adaptor> >
|
||||
{
|
||||
typedef ItemContainerHandler<Otherwise<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
OtherwiseHandler(Choose<string_type, string_adaptor>* choose,
|
||||
|
@ -89,6 +91,7 @@ private:
|
|||
template<class string_type, class string_adaptor>
|
||||
class ChooseHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
ChooseHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
context_(context),
|
||||
|
@ -112,9 +115,9 @@ public:
|
|||
return;
|
||||
} // if ...
|
||||
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI)
|
||||
{
|
||||
if(localName == "when")
|
||||
if(localName == SC::when)
|
||||
{
|
||||
seenWhere_ = true;
|
||||
if(seenOtherwise_)
|
||||
|
@ -129,7 +132,7 @@ public:
|
|||
return;
|
||||
} // if(localName == "when")
|
||||
|
||||
if(localName == "otherwise")
|
||||
if(localName == SC::otherwise)
|
||||
{
|
||||
if(seenOtherwise_)
|
||||
throw SAX::SAXException("xsl:choose may only have one xsl:otherwise element");
|
||||
|
@ -143,7 +146,7 @@ public:
|
|||
return;
|
||||
} // if(localName == "otherwise")
|
||||
} // if ...
|
||||
throw SAX::SAXException("xsl:choose can not contain " + qName + ". Only xsl:when and xsl:otherwise are allowed");
|
||||
throw SAX::SAXException("xsl:choose can not contain " + string_adaptor::asStdString(qName) + ". Only xsl:when and xsl:otherwise are allowed");
|
||||
} // startElement
|
||||
|
||||
virtual void endElement(const string_type& /* namespaceURI */,
|
||||
|
@ -158,7 +161,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:choose");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::choose);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
|
|
@ -7,21 +7,246 @@ namespace XSLT
|
|||
{
|
||||
|
||||
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
||||
struct StylesheetConstant
|
||||
struct StylesheetConstant : public Arabica::text::Unicode<typename string_adaptor::value_type>
|
||||
{
|
||||
static const string_type& NamespaceURI()
|
||||
{
|
||||
static string_type namespaceURI = "http://www.w3.org/1999/XSL/Transform";
|
||||
return namespaceURI;
|
||||
} // XSLTNamespaceURI
|
||||
static const string_type NamespaceURI;
|
||||
static const string_type Version;
|
||||
static const string_type Vendor;
|
||||
static const string_type VendorUrl;
|
||||
|
||||
static const string_type& Version()
|
||||
{
|
||||
static string_type version = "1.0";
|
||||
return version;
|
||||
} // Version
|
||||
static const string_type CDATAStart;
|
||||
static const string_type CDATAEnd;
|
||||
static const string_type CommentStart;
|
||||
static const string_type CommentEnd;
|
||||
static const string_type PIStart;
|
||||
static const string_type PIEnd;
|
||||
|
||||
static const string_type stylesheet;
|
||||
static const string_type transform;
|
||||
|
||||
static const string_type apply_imports;
|
||||
static const string_type apply_templates;
|
||||
static const string_type attribute;
|
||||
static const string_type attribute_set;
|
||||
static const string_type call_template;
|
||||
static const string_type choose;
|
||||
static const string_type comment;
|
||||
static const string_type copy;
|
||||
static const string_type copy_of;
|
||||
static const string_type decimal_format;
|
||||
static const string_type element;
|
||||
static const string_type fallback;
|
||||
static const string_type for_each;
|
||||
static const string_type if_;
|
||||
static const string_type import;
|
||||
static const string_type include;
|
||||
static const string_type key;
|
||||
static const string_type message;
|
||||
static const string_type namespace_alias;
|
||||
static const string_type number;
|
||||
static const string_type output;
|
||||
static const string_type param;
|
||||
static const string_type preserve_space;
|
||||
static const string_type processing_instruction;
|
||||
static const string_type strip_space;
|
||||
static const string_type template_;
|
||||
static const string_type text;
|
||||
static const string_type value_of;
|
||||
static const string_type variable;
|
||||
static const string_type sort;
|
||||
static const string_type with_param;
|
||||
static const string_type when;
|
||||
static const string_type otherwise;
|
||||
|
||||
static const string_type version;
|
||||
static const string_type extension_element_prefixes;
|
||||
static const string_type exclude_result_prefixes;
|
||||
static const string_type id;
|
||||
static const string_type href;
|
||||
static const string_type select;
|
||||
static const string_type name;
|
||||
static const string_type namespace_;
|
||||
static const string_type match;
|
||||
static const string_type mode;
|
||||
static const string_type priority;
|
||||
static const string_type use;
|
||||
static const string_type method;
|
||||
static const string_type indent;
|
||||
static const string_type omit_xml_declaration;
|
||||
static const string_type standalone;
|
||||
static const string_type space;
|
||||
static const string_type media_type;
|
||||
static const string_type encoding;
|
||||
static const string_type doctype_public;
|
||||
static const string_type doctype_system;
|
||||
static const string_type stylesheet_prefix;
|
||||
static const string_type result_prefix;
|
||||
static const string_type cdata_section_elements;
|
||||
static const string_type use_attribute_sets;
|
||||
static const string_type test;
|
||||
static const string_type lang;
|
||||
static const string_type data_type;
|
||||
static const string_type order;
|
||||
static const string_type case_order;
|
||||
static const string_type terminate;
|
||||
static const string_type disable_output_escaping;
|
||||
static const string_type hash_default;
|
||||
static const string_type no;
|
||||
static const string_type yes;
|
||||
static const string_type utf8;
|
||||
static const string_type ascending;
|
||||
static const string_type descending;
|
||||
static const string_type upper_first;
|
||||
static const string_type lower_first;
|
||||
static const string_type AllowedYesNo[];
|
||||
static const string_type DefaultPreserve[];
|
||||
|
||||
static const string_type double_hyphen;
|
||||
static const string_type escaped_double_hyphen;
|
||||
static const string_type escaped_pi_end;
|
||||
|
||||
static const string_type root_xpath;
|
||||
static const string_type current_xpath;
|
||||
static const string_type namespace_xpath;
|
||||
|
||||
static const string_type version_property;
|
||||
static const string_type vendor_property;
|
||||
static const string_type vendor_url_property;
|
||||
|
||||
static const string_type xml;
|
||||
static const string_type html;
|
||||
static const string_type xmlns_colon;
|
||||
static const string_type xmlns;
|
||||
static const string_type auto_ns;
|
||||
static const string_type xmlns_uri;
|
||||
static const string_type xml_uri;
|
||||
|
||||
static const string_type newline;
|
||||
}; // struct StylesheetConstant
|
||||
|
||||
#define STYLESHEETCONSTANT(What, Value) template<class string_type, class string_adaptor> const string_type StylesheetConstant<string_type, string_adaptor>::What = string_adaptor::construct_from_utf8(Value)
|
||||
|
||||
STYLESHEETCONSTANT(NamespaceURI, "http://www.w3.org/1999/XSL/Transform");
|
||||
STYLESHEETCONSTANT(Version, "1.0");
|
||||
STYLESHEETCONSTANT(Vendor, "Jez Higgins, JezUK Ltd");
|
||||
STYLESHEETCONSTANT(VendorUrl, "http://www.jezuk.co.uk/arabica/");
|
||||
|
||||
STYLESHEETCONSTANT(CDATAStart, "<[CDATA[");
|
||||
STYLESHEETCONSTANT(CDATAEnd, "]]>");
|
||||
STYLESHEETCONSTANT(CommentStart, "<!--");
|
||||
STYLESHEETCONSTANT(CommentEnd, "-->");
|
||||
STYLESHEETCONSTANT(PIStart, "<?");
|
||||
STYLESHEETCONSTANT(PIEnd, "?>");
|
||||
|
||||
STYLESHEETCONSTANT(stylesheet, "stylesheet");
|
||||
STYLESHEETCONSTANT(transform, "transform");
|
||||
|
||||
STYLESHEETCONSTANT(apply_imports, "apply-imports");
|
||||
STYLESHEETCONSTANT(apply_templates, "apply-templates");
|
||||
STYLESHEETCONSTANT(attribute, "attribute");
|
||||
STYLESHEETCONSTANT(attribute_set, "attribute-set");
|
||||
STYLESHEETCONSTANT(call_template, "call-template");
|
||||
STYLESHEETCONSTANT(choose, "choose");
|
||||
STYLESHEETCONSTANT(comment, "comment");
|
||||
STYLESHEETCONSTANT(copy, "copy");
|
||||
STYLESHEETCONSTANT(copy_of, "copy-of");
|
||||
STYLESHEETCONSTANT(decimal_format, "decimal-format");
|
||||
STYLESHEETCONSTANT(element, "element");
|
||||
STYLESHEETCONSTANT(fallback, "fallback");
|
||||
STYLESHEETCONSTANT(for_each, "for-each");
|
||||
STYLESHEETCONSTANT(if_, "if");
|
||||
STYLESHEETCONSTANT(import, "import");
|
||||
STYLESHEETCONSTANT(include, "include");
|
||||
STYLESHEETCONSTANT(key, "key");
|
||||
STYLESHEETCONSTANT(message, "message");
|
||||
STYLESHEETCONSTANT(namespace_alias, "namespace-alias");
|
||||
STYLESHEETCONSTANT(number, "number");
|
||||
STYLESHEETCONSTANT(output, "output");
|
||||
STYLESHEETCONSTANT(param, "param");
|
||||
STYLESHEETCONSTANT(preserve_space, "preserve-space");
|
||||
STYLESHEETCONSTANT(processing_instruction, "processing-instruction");
|
||||
STYLESHEETCONSTANT(strip_space, "strip-space");
|
||||
STYLESHEETCONSTANT(template_, "template");
|
||||
STYLESHEETCONSTANT(text, "text");
|
||||
STYLESHEETCONSTANT(value_of, "value-of");
|
||||
STYLESHEETCONSTANT(variable, "variable");
|
||||
STYLESHEETCONSTANT(sort, "sort");
|
||||
STYLESHEETCONSTANT(with_param, "with-param");
|
||||
STYLESHEETCONSTANT(when, "when");
|
||||
STYLESHEETCONSTANT(otherwise, "otherwise");
|
||||
|
||||
STYLESHEETCONSTANT(version, "version");
|
||||
STYLESHEETCONSTANT(extension_element_prefixes, "extension-element-prefixes");
|
||||
STYLESHEETCONSTANT(exclude_result_prefixes, "exclude-result-prefixes");
|
||||
STYLESHEETCONSTANT(id, "id");
|
||||
STYLESHEETCONSTANT(href, "href");
|
||||
STYLESHEETCONSTANT(select, "select");
|
||||
STYLESHEETCONSTANT(name, "name");
|
||||
STYLESHEETCONSTANT(namespace_, "namespace");
|
||||
STYLESHEETCONSTANT(match, "match");
|
||||
STYLESHEETCONSTANT(mode, "mode");
|
||||
STYLESHEETCONSTANT(priority, "priority");
|
||||
STYLESHEETCONSTANT(use, "use");
|
||||
STYLESHEETCONSTANT(method, "method");
|
||||
STYLESHEETCONSTANT(indent, "indent");
|
||||
STYLESHEETCONSTANT(omit_xml_declaration, "omit-xml-declaration");
|
||||
STYLESHEETCONSTANT(standalone, "standalone");
|
||||
STYLESHEETCONSTANT(space, "space");
|
||||
STYLESHEETCONSTANT(media_type, "media-type");
|
||||
STYLESHEETCONSTANT(encoding, "encoding");
|
||||
STYLESHEETCONSTANT(doctype_public, "doctype-public");
|
||||
STYLESHEETCONSTANT(doctype_system, "doctype-system");
|
||||
STYLESHEETCONSTANT(stylesheet_prefix, "stylesheet-prefix");
|
||||
STYLESHEETCONSTANT(result_prefix, "result-prefix");
|
||||
STYLESHEETCONSTANT(cdata_section_elements, "cdata-section-elements");
|
||||
STYLESHEETCONSTANT(use_attribute_sets, "use-attribute-sets");
|
||||
STYLESHEETCONSTANT(test, "test");
|
||||
STYLESHEETCONSTANT(disable_output_escaping, "disable-output-escaping");
|
||||
STYLESHEETCONSTANT(lang, "lang");
|
||||
STYLESHEETCONSTANT(data_type, "data-type");
|
||||
STYLESHEETCONSTANT(order, "order");
|
||||
STYLESHEETCONSTANT(case_order, "case-order");
|
||||
STYLESHEETCONSTANT(terminate, "terminate");
|
||||
STYLESHEETCONSTANT(hash_default, "#default");
|
||||
|
||||
STYLESHEETCONSTANT(no, "no");
|
||||
STYLESHEETCONSTANT(yes, "yes");
|
||||
STYLESHEETCONSTANT(utf8, "UTF-8");
|
||||
STYLESHEETCONSTANT(ascending, "ascending");
|
||||
STYLESHEETCONSTANT(descending, "descending");
|
||||
STYLESHEETCONSTANT(upper_first, "upper-first");
|
||||
STYLESHEETCONSTANT(lower_first, "lower-first");
|
||||
|
||||
STYLESHEETCONSTANT(double_hyphen, "--");
|
||||
STYLESHEETCONSTANT(escaped_double_hyphen, "- -");
|
||||
STYLESHEETCONSTANT(escaped_pi_end, "? >");
|
||||
|
||||
STYLESHEETCONSTANT(root_xpath, "/");
|
||||
STYLESHEETCONSTANT(current_xpath, ".");
|
||||
STYLESHEETCONSTANT(namespace_xpath, "namespace::node()");
|
||||
|
||||
STYLESHEETCONSTANT(version_property, "xsl:version");
|
||||
STYLESHEETCONSTANT(vendor_property, "xsl:vendor");
|
||||
STYLESHEETCONSTANT(vendor_url_property, "xsl:vendor-url");
|
||||
|
||||
STYLESHEETCONSTANT(xml, "xml");
|
||||
STYLESHEETCONSTANT(html, "html");
|
||||
STYLESHEETCONSTANT(xmlns_colon, "xmlns:");
|
||||
STYLESHEETCONSTANT(xmlns, "xmlns");
|
||||
STYLESHEETCONSTANT(auto_ns, "auto-ns");
|
||||
STYLESHEETCONSTANT(xmlns_uri, "http://www.w3.org/2000/xmlns");
|
||||
STYLESHEETCONSTANT(xml_uri, "http://www.w3.org/XML/1998/namespace");
|
||||
|
||||
STYLESHEETCONSTANT(newline, "\n");
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
const string_type StylesheetConstant<string_type, string_adaptor>::AllowedYesNo[] = { no, yes, string_adaptor::empty_string() };
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
const string_type StylesheetConstant<string_type, string_adaptor>::DefaultPreserve[] = { string_adaptor::construct_from_utf8("default"),
|
||||
string_adaptor::construct_from_utf8("preserve"),
|
||||
string_adaptor::empty_string() };
|
||||
#undef STYLESHEETCONSTANT
|
||||
} // namespace XSLT
|
||||
} // namespace Arabica
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class CopyHandler : public ItemContainerHandler<Copy<string_type, string_adaptor> >
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
CopyHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
ItemContainerHandler<Copy<string_type, string_adaptor> >(context)
|
||||
|
@ -22,9 +23,9 @@ public:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "use-attribute-sets", false, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
string_type sets = gatherAttributes(qName, atts, rules)["use-attribute-sets"];
|
||||
static const ValueRule<string_type> rules[] = { { SC::use_attribute_sets, false, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
string_type sets = gatherAttributes(qName, atts, rules)[SC::use_attribute_sets];
|
||||
|
||||
return new Copy<string_type, string_adaptor>(sets);
|
||||
} // createContainer
|
||||
|
@ -33,6 +34,7 @@ public:
|
|||
template<class string_type, class string_adaptor>
|
||||
class CopyOfHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
CopyOfHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
context_(context),
|
||||
|
@ -47,16 +49,16 @@ public:
|
|||
{
|
||||
if(copyOf_ == 0)
|
||||
{
|
||||
static const ValueRule rules[] = { { "select", true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
string_type select = gatherAttributes(qName, atts, rules)["select"];
|
||||
static const ValueRule<string_type> rules[] = { { SC::select, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
string_type select = gatherAttributes(qName, atts, rules)[SC::select];
|
||||
|
||||
copyOf_ = new CopyOf<string_type, string_adaptor>(context_.xpath_expression(select));
|
||||
|
||||
return;
|
||||
} // if(copyOf_ == 0)
|
||||
|
||||
throw SAX::SAXException(qName + " can not contain elements");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(qName) + " can not contain elements");
|
||||
} // startElement
|
||||
|
||||
virtual void endElement(const string_type& /* namespaceURI */,
|
||||
|
@ -69,7 +71,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:copy-of");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::copy_of);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& /* atts */)
|
||||
{
|
||||
throw SAX::SAXException("Haven't implemented " + qName + " yet");
|
||||
throw SAX::SAXException("Haven't implemented " + string_adaptor::asStdString(qName) + " yet");
|
||||
} // startElement
|
||||
}; // NotImplementedYetHandler
|
||||
|
||||
|
@ -40,7 +40,7 @@ struct ChildElement
|
|||
{
|
||||
typedef SAX::DefaultHandler<string_type, string_adaptor>* (*CreateHandlerPtr)(CompilationContext<string_type, string_adaptor>&);
|
||||
|
||||
const char* const name;
|
||||
const string_type name;
|
||||
CreateHandlerPtr createHandler;
|
||||
}; // struct ChildElement
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
|
|||
class ElementHandler : public ItemContainerHandler<Element<string_type, string_adaptor> >
|
||||
{
|
||||
typedef ItemContainerHandler<Element<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
ElementHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
ItemContainerHandler<Element<string_type, string_adaptor> >(context)
|
||||
|
@ -25,26 +26,27 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "name", true, 0, 0 },
|
||||
{ "namespace", false, "", 0 },
|
||||
{ "use-attribute-sets", false, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
|
||||
{ SC::namespace_, false, string_adaptor::empty_string(), 0 },
|
||||
{ SC::use_attribute_sets, false, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
|
||||
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> name = baseT::context().xpath_attribute_value_template(attrs["name"]);
|
||||
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> name =
|
||||
baseT::context().xpath_attribute_value_template(attrs[SC::name]);
|
||||
|
||||
if(attrs["use-attribute-sets"] != "")
|
||||
if(attrs[SC::use_attribute_sets] != string_adaptor::empty_string())
|
||||
throw SAX::SAXException("don't understand use-attribute-sets yet");
|
||||
|
||||
if(attrs["namespace"] == "")
|
||||
if(attrs[SC::namespace_] == string_adaptor::empty_string())
|
||||
return new Element<string_type, string_adaptor>(name,
|
||||
baseT::context().inScopeNamespaces(),
|
||||
attrs["use-attribute-sets"]);
|
||||
attrs[SC::use_attribute_sets]);
|
||||
|
||||
return new Element<string_type, string_adaptor>(name,
|
||||
baseT::context().xpath_attribute_value_template(attrs["namespace"]),
|
||||
attrs["use-attribute-sets"]);
|
||||
baseT::context().xpath_attribute_value_template(attrs[SC::namespace_]),
|
||||
attrs[SC::use_attribute_sets]);
|
||||
} // createContainer
|
||||
}; // class ElementHandler
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class ForEachHandler : public ItemContainerHandler<ForEach<string_type, string_adaptor> >
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
typedef ItemContainerHandler<ForEach<string_type, string_adaptor> > baseT;
|
||||
|
||||
public:
|
||||
|
@ -28,9 +29,9 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "select", true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
string_type select = gatherAttributes(qName, atts, rules)["select"];
|
||||
static const ValueRule<string_type> rules[] = { { SC::select, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
string_type select = gatherAttributes(qName, atts, rules)[SC::select];
|
||||
|
||||
return new ForEach<string_type, string_adaptor>(baseT::context().xpath_expression(select));
|
||||
} // createContainer
|
||||
|
@ -40,8 +41,8 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) &&
|
||||
(localName == "sort"))
|
||||
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI) &&
|
||||
(localName == SC::sort))
|
||||
{
|
||||
if(!done_sort_)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class IfHandler : public ItemContainerHandler<If<string_type, string_adaptor> >
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
IfHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
ItemContainerHandler<If<string_type, string_adaptor> >(context)
|
||||
|
@ -23,9 +24,9 @@ public:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "test", true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
string_type test = gatherAttributes(qName, atts, rules)["test"];
|
||||
static const ValueRule<string_type> rules[] = { { SC::test, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
string_type test = gatherAttributes(qName, atts, rules)[SC::test];
|
||||
|
||||
return new If<string_type, string_adaptor>(ItemContainerHandler<If<string_type, string_adaptor> >::context().xpath_expression(test));
|
||||
} // startElement
|
||||
|
|
|
@ -14,6 +14,7 @@ template<class string_type, class string_adaptor>
|
|||
class IncludeHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
struct ImportHref;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
IncludeHandler() :
|
||||
|
@ -52,19 +53,19 @@ public:
|
|||
if(no_content_)
|
||||
throw SAX::SAXException("xsl:include must be empty");
|
||||
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI)
|
||||
{
|
||||
if(localName == "import")
|
||||
if(localName == SC::import)
|
||||
{
|
||||
string_type href = validate_href(qName, atts);
|
||||
import_stack_.push_back(href, context_->next_precedence(), current_includes_);
|
||||
return;
|
||||
} // if(localName == "import")
|
||||
if(localName == "include")
|
||||
} // if ...
|
||||
if(localName == SC::include)
|
||||
{
|
||||
href_.push_back(validate_href(qName, atts));
|
||||
return;
|
||||
} // if(localName == "include")
|
||||
} // if ...
|
||||
} // if ...
|
||||
|
||||
context_->parentHandler().startElement(namespaceURI,
|
||||
|
@ -84,10 +85,10 @@ public:
|
|||
const string_type& qName)
|
||||
{
|
||||
if(no_content_ &&
|
||||
(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI()))
|
||||
(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI))
|
||||
{
|
||||
no_content_ = false;
|
||||
if(localName == "include")
|
||||
if(localName == SC::include)
|
||||
{
|
||||
include_stylesheet(href_.back(), context_->precedence());
|
||||
href_.pop_back();
|
||||
|
@ -105,7 +106,7 @@ public:
|
|||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
if(no_content_)
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:include/xsl:import");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::include + SC::import);
|
||||
context_->parentHandler().characters(ch);
|
||||
} // characters
|
||||
|
||||
|
@ -121,9 +122,9 @@ public:
|
|||
private:
|
||||
string_type validate_href(const string_type& qName, const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "href", true, 0, 0 },
|
||||
static const ValueRule<string_type> rules[] = { { SC::href, true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
string_type href = gatherAttributes(qName, atts, rules)["href"];
|
||||
string_type href = gatherAttributes(qName, atts, rules)[SC::href];
|
||||
no_content_ = true;
|
||||
// std::cout << "Base : " << context_->currentBase() << ", href : " << href << "\n";
|
||||
return context_->makeAbsolute(href);
|
||||
|
@ -133,9 +134,9 @@ private:
|
|||
{
|
||||
if(std::find(current_includes_.begin(), current_includes_.end(), href) != current_includes_.end())
|
||||
{
|
||||
string_type error = "Stylesheet '" + href + "' includes/imports itself ";
|
||||
std::string error = "Stylesheet '" + string_adaptor::asStdString(href) + "' includes/imports itself ";
|
||||
for(HrefStack::const_iterator i = current_includes_.begin(), ie = current_includes_.end(); i != ie; ++i)
|
||||
error += "\n " + *i;
|
||||
error += "\n " + string_adaptor::asStdString(*i);
|
||||
throw std::runtime_error(error);
|
||||
} // if ...
|
||||
} // check_for_loops
|
||||
|
@ -166,7 +167,7 @@ private:
|
|||
context_->setBase(prev);
|
||||
|
||||
if(errorHandler.errorsReported())
|
||||
throw std::runtime_error("Could not import/include stylesheet '" + href + "' - " + errorHandler.errors());
|
||||
throw std::runtime_error("Could not import/include stylesheet '" + string_adaptor::asStdString(href) + "' - " + errorHandler.errors());
|
||||
|
||||
current_includes_.pop_back();
|
||||
} // include_stylesheet
|
||||
|
|
|
@ -14,6 +14,8 @@ template<class string_type, class string_adaptor>
|
|||
class InlineElementHandler : public ItemContainerHandler<InlineElement<string_type, string_adaptor> >
|
||||
{
|
||||
typedef ItemContainerHandler<InlineElement<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
InlineElementHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
baseT(context)
|
||||
|
@ -29,9 +31,9 @@ protected:
|
|||
std::vector<InlineAttribute<string_type, string_adaptor> > inlineAtts;
|
||||
for(int i = 0; i != atts.getLength(); ++i)
|
||||
{
|
||||
if(atts.getQName(i).find("xmlns:") == 0)
|
||||
if(atts.getQName(i).find(SC::xmlns_colon) == 0)
|
||||
continue;
|
||||
if(atts.getURI(i) == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
|
||||
if(atts.getURI(i) == StylesheetConstant<string_type, string_adaptor>::NamespaceURI)
|
||||
continue;
|
||||
if(!baseT::context().isRemapped(atts.getURI(i)))
|
||||
inlineAtts.push_back(InlineAttribute<string_type, string_adaptor>(atts.getQName(i),
|
||||
|
@ -42,7 +44,7 @@ protected:
|
|||
std::pair<string_type, string_type> remap = baseT::context().remappedNamespace(atts.getURI(i));
|
||||
if(remap.first.empty() && !remap.second.empty())
|
||||
remap.first = baseT::context().autoNamespacePrefix();
|
||||
string_type name = remap.first + ":" + atts.getLocalName(i);
|
||||
string_type name = remap.first + SC::COLON + atts.getLocalName(i);
|
||||
inlineAtts.push_back(InlineAttribute<string_type, string_adaptor>(name,
|
||||
remap.second,
|
||||
baseT::context().xpath_attribute_value_template(atts.getValue(i))));
|
||||
|
@ -53,7 +55,7 @@ protected:
|
|||
return new InlineElement<string_type, string_adaptor>(qName, namespaceURI, inlineAtts);
|
||||
|
||||
const std::pair<string_type, string_type>& remap = baseT::context().remappedNamespace(namespaceURI);
|
||||
string_type name = remap.first + ":" + localName;
|
||||
string_type name = remap.first + SC::COLON + localName;
|
||||
return new InlineElement<string_type, string_adaptor>(name, remap.second, inlineAtts);
|
||||
} // createContainer
|
||||
}; // class InlineElementHandler
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
if(createChild(namespaceURI, localName, qName, atts))
|
||||
return;
|
||||
|
||||
throw SAX::SAXException(qName + " <- Sorry, don't know about that yet :)");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(qName) + " <- Sorry, don't know about that yet :)");
|
||||
} // startElement
|
||||
|
||||
virtual void endElement(const string_type& /* namespaceURI */,
|
||||
|
@ -85,9 +85,11 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI)
|
||||
{
|
||||
for(const ChildElement<string_type, string_adaptor>* c = AllowedChildren<string_type, string_adaptor>(); c->name != 0; ++c)
|
||||
for(const ChildElement<string_type, string_adaptor>* c = AllowedChildren<string_type, string_adaptor>();
|
||||
c->name != string_adaptor::empty_string();
|
||||
++c)
|
||||
if(c->name == localName)
|
||||
{
|
||||
context_.push(container_,
|
||||
|
@ -144,27 +146,29 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
const ChildElement<string_type, string_adaptor>* AllowedChildren()
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
static const ChildElement<string_type, string_adaptor> allowedChildren[] =
|
||||
{
|
||||
{ "apply-imports", CreateHandler<ApplyImportsHandler<string_type, string_adaptor> > },
|
||||
{ "apply-templates", CreateHandler<ApplyTemplatesHandler<string_type, string_adaptor> > },
|
||||
{ "attribute", CreateHandler<AttributeHandler<string_type, string_adaptor> > },
|
||||
{ "call-template", CreateHandler<CallTemplateHandler<string_type, string_adaptor> > },
|
||||
{ "choose", CreateHandler<ChooseHandler<string_type, string_adaptor> > },
|
||||
{ "comment", CreateHandler<CommentHandler<string_type, string_adaptor> > },
|
||||
{ "copy", CreateHandler<CopyHandler<string_type, string_adaptor> > },
|
||||
{ "copy-of", CreateHandler<CopyOfHandler<string_type, string_adaptor> > },
|
||||
{ "element", CreateHandler<ElementHandler<string_type, string_adaptor> > },
|
||||
{ "fallback", CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ "for-each", CreateHandler<ForEachHandler<string_type, string_adaptor> > },
|
||||
{ "if", CreateHandler<IfHandler<string_type, string_adaptor> > },
|
||||
{ "message", CreateHandler<MessageHandler<string_type, string_adaptor> >},
|
||||
{ "number", CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ "processing-instruction", CreateHandler<ProcessingInstructionHandler<string_type, string_adaptor> > },
|
||||
{ "text", CreateHandler<TextHandler<string_type, string_adaptor> > },
|
||||
{ "value-of", CreateHandler<ValueOfHandler<string_type, string_adaptor> > },
|
||||
{ "variable", CreateHandler<VariableHandler<Variable<string_type, string_adaptor> > > },
|
||||
{ 0, 0 }
|
||||
{ SC::apply_imports, CreateHandler<ApplyImportsHandler<string_type, string_adaptor> > },
|
||||
{ SC::apply_templates, CreateHandler<ApplyTemplatesHandler<string_type, string_adaptor> > },
|
||||
{ SC::attribute, CreateHandler<AttributeHandler<string_type, string_adaptor> > },
|
||||
{ SC::call_template, CreateHandler<CallTemplateHandler<string_type, string_adaptor> > },
|
||||
{ SC::choose, CreateHandler<ChooseHandler<string_type, string_adaptor> > },
|
||||
{ SC::comment, CreateHandler<CommentHandler<string_type, string_adaptor> > },
|
||||
{ SC::copy, CreateHandler<CopyHandler<string_type, string_adaptor> > },
|
||||
{ SC::copy_of, CreateHandler<CopyOfHandler<string_type, string_adaptor> > },
|
||||
{ SC::element, CreateHandler<ElementHandler<string_type, string_adaptor> > },
|
||||
{ SC::fallback, CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ SC::for_each, CreateHandler<ForEachHandler<string_type, string_adaptor> > },
|
||||
{ SC::if_, CreateHandler<IfHandler<string_type, string_adaptor> > },
|
||||
{ SC::message, CreateHandler<MessageHandler<string_type, string_adaptor> >},
|
||||
{ SC::number, CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ SC::processing_instruction, CreateHandler<ProcessingInstructionHandler<string_type, string_adaptor> > },
|
||||
{ SC::text, CreateHandler<TextHandler<string_type, string_adaptor> > },
|
||||
{ SC::value_of, CreateHandler<ValueOfHandler<string_type, string_adaptor> > },
|
||||
{ SC::variable, CreateHandler<VariableHandler<Variable<string_type, string_adaptor> > > },
|
||||
{ string_adaptor::empty_string(), 0 }
|
||||
};
|
||||
return allowedChildren;
|
||||
} // AllowedChildren
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class KeyHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
typedef typename Key<string_type, string_adaptor>::MatchExprList MatchExprList;
|
||||
public:
|
||||
KeyHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
|
@ -26,19 +27,19 @@ public:
|
|||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
if(key_ != 0)
|
||||
throw SAX::SAXException(qName + " can not contain elements");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(qName) + " can not contain elements");
|
||||
|
||||
static const ValueRule rules[] = { { "name", true, 0, 0 },
|
||||
{ "match", true, 0, 0 },
|
||||
{ "use", true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
|
||||
{ SC::match, true, 0, 0 },
|
||||
{ SC::use, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
name_ = context_.processInternalQName(attrs["name"]).clarkName();
|
||||
name_ = context_.processInternalQName(attrs[SC::name]).clarkName();
|
||||
try
|
||||
{
|
||||
MatchExprList matches = context_.xpath_match_no_variables(attrs["match"]);
|
||||
Arabica::XPath::XPathExpression<string_type, string_adaptor> use = context_.xpath_expression_no_variables(attrs["use"]);
|
||||
MatchExprList matches = context_.xpath_match_no_variables(attrs[SC::match]);
|
||||
Arabica::XPath::XPathExpression<string_type, string_adaptor> use = context_.xpath_expression_no_variables(attrs[SC::use]);
|
||||
|
||||
key_ = new Key<string_type, string_adaptor>(matches, use);
|
||||
} // try
|
||||
|
@ -58,7 +59,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:key");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::key);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
|
|||
class MessageHandler : public ItemContainerHandler<Message<string_type, string_adaptor> >
|
||||
{
|
||||
typedef ItemContainerHandler<Message<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
MessageHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
baseT(context)
|
||||
|
@ -25,9 +26,9 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "terminate", false, No, AllowedYesNo },
|
||||
{ 0, false, 0, 0 } };
|
||||
return new Message<string_type, string_adaptor>(gatherAttributes(qName, atts, rules)["terminate"] == Yes);
|
||||
static const ValueRule<string_type> rules[] = { { SC::terminate, false, SC::no, SC::AllowedYesNo },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
return new Message<string_type, string_adaptor>(gatherAttributes(qName, atts, rules)[SC::terminate] == SC::yes);
|
||||
} // createContainer
|
||||
}; // class MessageHandler
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <XML/XMLCharacterClasses.hpp>
|
||||
|
||||
#include "xslt_constants.hpp"
|
||||
|
||||
namespace Arabica
|
||||
{
|
||||
namespace XSLT
|
||||
|
@ -11,6 +13,8 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class NamespaceAliasHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
NamespaceAliasHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
context_(context),
|
||||
|
@ -25,32 +29,32 @@ public:
|
|||
{
|
||||
if(!done_)
|
||||
{
|
||||
static const ValueRule rules[] = { { "stylesheet-prefix", true, 0, 0 },
|
||||
{ "result-prefix", true, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static const ValueRule<string_type> rules[] = { { SC::stylesheet_prefix, true, 0, 0 },
|
||||
{ SC::result_prefix, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
string_type stylesheet_prefix = attrs["stylesheet-prefix"];
|
||||
string_type result_prefix = attrs["result-prefix"];
|
||||
string_type stylesheet_prefix = attrs[SC::stylesheet_prefix];
|
||||
string_type result_prefix = attrs[SC::result_prefix];
|
||||
|
||||
if(stylesheet_prefix == "#default")
|
||||
stylesheet_prefix = "";
|
||||
if(result_prefix == "#default")
|
||||
result_prefix = "";
|
||||
if(stylesheet_prefix == SC::hash_default)
|
||||
stylesheet_prefix = string_adaptor::empty_string();
|
||||
if(result_prefix == SC::hash_default)
|
||||
result_prefix = string_adaptor::empty_string();
|
||||
|
||||
std::map<string_type, string_type> namespaces = context_.inScopeNamespaces();
|
||||
if((namespaces.find(stylesheet_prefix) == namespaces.end()) &&
|
||||
(!stylesheet_prefix.empty()))
|
||||
throw SAX::SAXException("xslt:namespace-alias " + stylesheet_prefix + " is not a declared namespace prefix");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(SC::namespace_alias) + " " + string_adaptor::asStdString(stylesheet_prefix) + " is not a declared namespace prefix");
|
||||
if((namespaces.find(result_prefix) == namespaces.end()) &&
|
||||
(!result_prefix.empty()))
|
||||
throw SAX::SAXException("xslt:namespace-alias " + result_prefix + " is not a declared namespace prefix");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(SC::namespace_alias) + " " + string_adaptor::asStdString(result_prefix) + " is not a declared namespace prefix");
|
||||
|
||||
context_.addNamespaceAlias(namespaces[stylesheet_prefix], result_prefix, namespaces[result_prefix]);
|
||||
return;
|
||||
} // if(!done_)
|
||||
|
||||
throw SAX::SAXException(qName + " can not contain elements");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(qName) + " can not contain elements");
|
||||
} // startElement
|
||||
|
||||
virtual void endElement(const string_type& /* namespaceURI */,
|
||||
|
@ -62,7 +66,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:namespace-alias");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::namespace_alias);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class OutputHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
OutputHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
context_(context)
|
||||
|
@ -22,25 +24,26 @@ public:
|
|||
{
|
||||
if(settings_.empty())
|
||||
{
|
||||
static const char* AllowedMethods[] = { "xml", "html", "text", 0 };
|
||||
static const ValueRule rules[] = { { "method", false, "xml", AllowedMethods },
|
||||
{ "version", false, "1.0", 0 },
|
||||
{ "encoding", false, "UTF-8", 0 },
|
||||
{ "omit-xml-declaration", false, No, AllowedYesNo },
|
||||
{ "standalone", false, "", AllowedYesNo },
|
||||
{ "doctype-public", false, "", 0},
|
||||
{ "doctype-system", false, "", 0},
|
||||
{ "cdata-section-elements", false, "", 0},
|
||||
{ "indent", false, No, AllowedYesNo },
|
||||
{ "media-type", false, "", 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static string_type AllowedMethods[] = { SC::xml, SC::html, SC::text, string_adaptor::empty_string() };
|
||||
static const ValueRule<string_type> rules[] =
|
||||
{ { SC::method, false, SC::xml, AllowedMethods },
|
||||
{ SC::version, false, SC::Version, 0 },
|
||||
{ SC::encoding, false, SC::utf8, 0 },
|
||||
{ SC::omit_xml_declaration, false, SC::no, SC::AllowedYesNo },
|
||||
{ SC::standalone, false, string_adaptor::empty_string(), SC::AllowedYesNo },
|
||||
{ SC::doctype_public, false, string_adaptor::empty_string(), 0 },
|
||||
{ SC::doctype_system, false, string_adaptor::empty_string(), 0 },
|
||||
{ SC::cdata_section_elements, false, string_adaptor::empty_string(), 0 },
|
||||
{ SC::indent, false, SC::no, SC::AllowedYesNo },
|
||||
{ SC::media_type, false, string_adaptor::empty_string(), 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
settings_ = gatherAttributes(qName, atts, rules);
|
||||
cdataElements_ = extractCDATAElements(settings_["cdata-section-elements"]);
|
||||
cdataElements_ = extractCDATAElements(settings_[SC::cdata_section_elements]);
|
||||
|
||||
return;
|
||||
} // if(settings_ == 0)
|
||||
|
||||
throw SAX::SAXException(qName + " can not contain elements");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(qName) + " can not contain elements");
|
||||
} // startElement
|
||||
|
||||
virtual void endElement(const string_type& /* namespaceURI */,
|
||||
|
@ -53,7 +56,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:output");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::output);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
@ -67,7 +70,8 @@ private:
|
|||
if(cdata_section_elements.empty())
|
||||
return elements;
|
||||
|
||||
std::istringstream is(text::normalize_whitespace<string_type, string_adaptor>(cdata_section_elements));
|
||||
std::basic_istringstream<string_adaptor::value_type>
|
||||
is(text::normalize_whitespace<string_type, string_adaptor>(cdata_section_elements));
|
||||
while(!is.eof())
|
||||
{
|
||||
string_type e;
|
||||
|
|
|
@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
|
|||
class ProcessingInstructionHandler : public ItemContainerHandler<ProcessingInstruction<string_type, string_adaptor> >
|
||||
{
|
||||
typedef ItemContainerHandler<ProcessingInstruction<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
ProcessingInstructionHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
|
@ -25,9 +26,9 @@ public:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "name", true, 0, 0 },
|
||||
{ 0, false, 0, 0} };
|
||||
string_type name = gatherAttributes(qName, atts, rules)["name"];
|
||||
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0} };
|
||||
string_type name = gatherAttributes(qName, atts, rules)[SC::name];
|
||||
|
||||
return new ProcessingInstruction<string_type, string_adaptor>(baseT::context().xpath_attribute_value_template(name));
|
||||
} // createContainer
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class SortHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
SortHandler(CompilationContext<string_type, string_adaptor>& context,
|
||||
Sortable<string_type, string_adaptor>& sortee) :
|
||||
|
@ -27,22 +29,22 @@ public:
|
|||
{
|
||||
if(sort_ == 0)
|
||||
{
|
||||
static const ValueRule rules[] = { { "select", false, ".", 0 },
|
||||
{ "lang", false, 0, 0 },
|
||||
{ "data-type", false, "text", 0 },
|
||||
{ "order", false, "ascending", 0 },
|
||||
{ "case-order", false, "upper-first", 0 },
|
||||
static const ValueRule<string_type> rules[] = { { SC::select, false, SC::current_xpath, 0 },
|
||||
{ SC::lang, false, 0, 0 },
|
||||
{ SC::data_type, false, SC::text, 0 },
|
||||
{ SC::order, false, SC::ascending, 0 },
|
||||
{ SC::case_order, false, SC::upper_first, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
|
||||
std::map<string_type, string_type> attr = gatherAttributes(qName, atts, rules);
|
||||
|
||||
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> select, lang, datatype, order, caseorder;
|
||||
select = context_.xpath_expression(attr["select"]);
|
||||
datatype = context_.xpath_attribute_value_template(attr["data-type"]);
|
||||
order = context_.xpath_attribute_value_template(attr["order"]);
|
||||
caseorder = context_.xpath_attribute_value_template(attr["case-order"]);
|
||||
select = context_.xpath_expression(attr[SC::select]);
|
||||
datatype = context_.xpath_attribute_value_template(attr[SC::data_type]);
|
||||
order = context_.xpath_attribute_value_template(attr[SC::order]);
|
||||
caseorder = context_.xpath_attribute_value_template(attr[SC::case_order]);
|
||||
|
||||
if(attr["lang"].length() != 0)
|
||||
if(attr[SC::lang].length() != 0)
|
||||
std::cerr << "Sorry! Don't support xsl:sort lang attribute yet" << std::endl;
|
||||
|
||||
sort_ = new Sort<string_type, string_adaptor>(select,
|
||||
|
@ -66,7 +68,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:sort");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::sort);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,6 +13,7 @@ template<class string_type, class string_adaptor>
|
|||
class TemplateHandler : public ItemContainerHandler<Template<string_type, string_adaptor> >
|
||||
{
|
||||
typedef ItemContainerHandler<Template<string_type, string_adaptor> > baseT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
TemplateHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
baseT(context),
|
||||
|
@ -41,40 +42,40 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "match", false, 0, 0 },
|
||||
{ "mode", false, 0, 0 },
|
||||
{ "name", false, 0, 0 },
|
||||
{ "priority", false, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static const ValueRule<string_type> rules[] = { { SC::match, false, 0, 0 },
|
||||
{ SC::mode, false, 0, 0 },
|
||||
{ SC::name, false, 0, 0 },
|
||||
{ SC::priority, false, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
std::map<string_type, string_type> attributes = gatherAttributes(qName, atts, rules);
|
||||
|
||||
const string_type& match = attributes["match"];
|
||||
if((match == "") && (attributes["name"] == ""))
|
||||
const string_type& match = attributes[SC::match];
|
||||
if((match == string_adaptor::empty_string()) && (attributes[SC::name] == string_adaptor::empty_string()))
|
||||
throw SAX::SAXException("xsl:template must have a match and/or a name attribute");
|
||||
|
||||
int index = atts.getIndex("mode");
|
||||
int index = atts.getIndex(SC::mode);
|
||||
if(index != -1)
|
||||
{
|
||||
const string_type& mode = attributes["mode"];
|
||||
if(mode == "")
|
||||
const string_type& mode = attributes[SC::mode];
|
||||
if(mode == string_adaptor::empty_string())
|
||||
throw SAX::SAXException("xsl:template mode cannot be empty");
|
||||
if(match == "")
|
||||
if(match == string_adaptor::empty_string())
|
||||
throw SAX::SAXException("xsl:template may not have a mode without a match");
|
||||
} // ...
|
||||
|
||||
const string_type& priority = attributes["priority"];
|
||||
if((atts.getIndex("priority") != -1) && (priority == ""))
|
||||
const string_type& priority = attributes[SC::priority];
|
||||
if((atts.getIndex(SC::priority) != -1) && (priority == string_adaptor::empty_string()))
|
||||
throw SAX::SAXException("xsl:template priority cannot be empty");
|
||||
|
||||
string_type name;
|
||||
if(attributes["name"] != "")
|
||||
name = baseT::context().processInternalQName(attributes["name"]).clarkName();
|
||||
if(attributes[SC::name] != string_adaptor::empty_string())
|
||||
name = baseT::context().processInternalQName(attributes[SC::name]).clarkName();
|
||||
|
||||
string_type mode;
|
||||
if(attributes["mode"] != "")
|
||||
mode = baseT::context().processInternalQName(attributes["mode"]).clarkName();
|
||||
if(attributes[SC::mode] != string_adaptor::empty_string())
|
||||
mode = baseT::context().processInternalQName(attributes[SC::mode]).clarkName();
|
||||
|
||||
if(match == "")
|
||||
if(match == string_adaptor::empty_string())
|
||||
return new Template<string_type, string_adaptor>(name,
|
||||
mode,
|
||||
priority,
|
||||
|
@ -92,8 +93,8 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) &&
|
||||
(localName == "param"))
|
||||
if((namespaceURI == SC::NamespaceURI) &&
|
||||
(localName == SC::param))
|
||||
{
|
||||
if(!done_params_)
|
||||
{
|
||||
|
|
|
@ -11,6 +11,8 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class TextHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
TextHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
context_(context),
|
||||
|
@ -25,13 +27,13 @@ public:
|
|||
{
|
||||
if(text_ == 0)
|
||||
{
|
||||
static const ValueRule rules[] = { { "disable-output-escaping", false, No, AllowedYesNo },
|
||||
{ 0, false, 0, 0 } };
|
||||
text_ = new Text<string_type, string_adaptor>(gatherAttributes(qName, atts, rules)["disable-output-escaping"] == Yes);
|
||||
static const ValueRule<string_type> rules[] = { { SC::disable_output_escaping, false, SC::no, SC::AllowedYesNo },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
text_ = new Text<string_type, string_adaptor>(gatherAttributes(qName, atts, rules)[SC::disable_output_escaping] == SC::yes);
|
||||
return;
|
||||
} // if(text_ == 0)
|
||||
|
||||
throw SAX::SAXException(qName + " can not contain elements");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(qName) + " can not contain elements");
|
||||
} // startElement
|
||||
|
||||
virtual void endElement(const string_type& /* namespaceURI */,
|
||||
|
|
|
@ -12,6 +12,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class ValueOfHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
ValueOfHandler(CompilationContext<string_type, string_adaptor>& context) :
|
||||
context_(context),
|
||||
|
@ -26,17 +27,17 @@ public:
|
|||
{
|
||||
if(valueOf_ == 0)
|
||||
{
|
||||
static const ValueRule rules[] = { { "select", true, 0, 0 },
|
||||
{ "disable-output-escaping", false, No, AllowedYesNo },
|
||||
static const ValueRule<string_type> rules[] = { { SC::select, true, 0, 0 },
|
||||
{ SC::disable_output_escaping, false, SC::no, SC::AllowedYesNo },
|
||||
{ 0, false, 0, 0 } };
|
||||
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
valueOf_ = new ValueOf<string_type, string_adaptor>(context_.xpath_expression(attrs["select"]),
|
||||
attrs["disable-output-escaping"] == Yes);
|
||||
valueOf_ = new ValueOf<string_type, string_adaptor>(context_.xpath_expression(attrs[SC::select]),
|
||||
attrs[SC::disable_output_escaping] == SC::yes);
|
||||
return;
|
||||
} // if(valueOf_ == 0)
|
||||
|
||||
throw SAX::SAXException(qName + " can not contain elements");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(qName) + " can not contain elements");
|
||||
} // startElement
|
||||
|
||||
virtual void endElement(const string_type& /* namespaceURI */,
|
||||
|
@ -49,7 +50,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:value-of");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::value_of);
|
||||
} // characters
|
||||
|
||||
private:
|
||||
|
|
|
@ -6,105 +6,105 @@ namespace Arabica
|
|||
namespace XSLT
|
||||
{
|
||||
|
||||
template<class string_type>
|
||||
struct ValueRule
|
||||
{
|
||||
const char* name;
|
||||
const string_type name;
|
||||
bool mandatory;
|
||||
const char* default_value;
|
||||
const char** allowed;
|
||||
const string_type default_value;
|
||||
const string_type* allowed;
|
||||
}; // struct ValueRule
|
||||
|
||||
static const char* No = "no";
|
||||
static const char* Yes = "yes";
|
||||
static const char* AllowedYesNo[] = { No, Yes, 0 };
|
||||
static const char* DefaultPreserve[] = { "default", "preserve", 0 };
|
||||
|
||||
template<class string_type>
|
||||
template<class string_type, class string_adaptor>
|
||||
void validateValues(const string_type& parentElement,
|
||||
const string_type& name,
|
||||
const string_type& value,
|
||||
const char** allowed)
|
||||
const string_type allowed[])
|
||||
{
|
||||
for(const char* const* a = allowed; *a != 0; ++a)
|
||||
for(const string_type* a = allowed; *a != string_adaptor::empty_string(); ++a)
|
||||
if(value == *a)
|
||||
return;
|
||||
|
||||
std::ostringstream os;
|
||||
os << parentElement + ": " + name + " may be one of ";
|
||||
while(*allowed != 0)
|
||||
os << '\'' << *allowed++ << "' ";
|
||||
os << string_adaptor::asStdString(parentElement) + ": " + string_adaptor::asStdString(name) + " may be one of ";
|
||||
while(*allowed != string_adaptor::empty_string())
|
||||
os << '\'' << string_adaptor::asStdString(*allowed++) << "' ";
|
||||
throw SAX::SAXException(os.str());
|
||||
} // validateValues
|
||||
|
||||
template<class string_type>
|
||||
template<class string_type, class string_adaptor>
|
||||
void validateXmlAttribute(const string_type& parentElement,
|
||||
const string_type& name,
|
||||
const string_type& value,
|
||||
std::map<string_type, string_type>& results)
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
results[name] = value;
|
||||
|
||||
if(name == "space")
|
||||
validateValues(parentElement, name, value, DefaultPreserve);
|
||||
if(name == SC::space)
|
||||
validateValues<string_type, string_adaptor>(parentElement, name, value, SC::DefaultPreserve);
|
||||
} // validateXmlAttribute
|
||||
|
||||
template<class string_type>
|
||||
template<class string_type, class string_adaptor>
|
||||
void validateAttribute(const string_type& parentElement,
|
||||
const string_type& name,
|
||||
const string_type& value,
|
||||
const ValueRule* rules,
|
||||
const ValueRule<string_type>* rules,
|
||||
std::map<string_type, string_type>& results)
|
||||
{
|
||||
while((rules->name != 0) && (name != rules->name))
|
||||
while((rules->name != string_adaptor::empty_string()) && (name != rules->name))
|
||||
++rules;
|
||||
|
||||
if(rules->name == 0)
|
||||
throw SAX::SAXException(parentElement + ": Illegal attribute " + name);
|
||||
if(rules->name == string_adaptor::empty_string())
|
||||
throw SAX::SAXException(string_adaptor::asStdString(parentElement) + ": Illegal attribute " + string_adaptor::asStdString(name));
|
||||
|
||||
results[name] = value;
|
||||
|
||||
if(rules->allowed != 0)
|
||||
validateValues(parentElement, name, value, rules->allowed);
|
||||
validateValues<string_type, string_adaptor>(parentElement, name, value, rules->allowed);
|
||||
} // validateAttribute
|
||||
|
||||
template<class string_type, class string_adaptor>
|
||||
std::map<string_type, string_type> gatherAttributes(const string_type& parentElement,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts,
|
||||
const ValueRule* rules)
|
||||
const ValueRule<string_type>* rules)
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
std::map<string_type, string_type> results;
|
||||
|
||||
for(const ValueRule* r = rules ; r->name != 0; ++r)
|
||||
for(const ValueRule<string_type>* r = rules ; r->name != string_adaptor::empty_string(); ++r)
|
||||
{
|
||||
if((r->mandatory) && (atts.getValue(r->name).empty()))
|
||||
throw SAX::SAXException(parentElement + ": Attribute " + r->name + " must be specified");
|
||||
if(r->default_value)
|
||||
throw SAX::SAXException(string_adaptor::asStdString(parentElement) + ": Attribute " + string_adaptor::asStdString(r->name) + " must be specified");
|
||||
if(r->default_value != string_adaptor::empty_string())
|
||||
results[r->name] = r->default_value;
|
||||
} //
|
||||
|
||||
for(int a = 0; a < atts.getLength(); ++a)
|
||||
{
|
||||
if(atts.getLocalName(a) == "")
|
||||
if(atts.getLocalName(a) == string_adaptor::empty_string())
|
||||
continue; // namespace decl
|
||||
if(atts.getURI(a) == "http://www.w3.org/XML/1998/namespace")
|
||||
if(atts.getURI(a) == SC::xml_uri)
|
||||
{
|
||||
validateXmlAttribute(parentElement, atts.getLocalName(a), atts.getValue(a), results); // special xml: attributes
|
||||
validateXmlAttribute<string_type, string_adaptor>(parentElement, atts.getLocalName(a), atts.getValue(a), results); // special xml: attributes
|
||||
continue;
|
||||
}
|
||||
if(atts.getURI(a) == "")
|
||||
validateAttribute(parentElement, atts.getLocalName(a), atts.getValue(a), rules, results);
|
||||
if(atts.getURI(a) == string_adaptor::empty_string())
|
||||
validateAttribute<string_type, string_adaptor>(parentElement, atts.getLocalName(a), atts.getValue(a), rules, results);
|
||||
}
|
||||
|
||||
return results;
|
||||
} // validateAttributes
|
||||
|
||||
template<class string_type>
|
||||
template<class string_type, class string_adaptor>
|
||||
void verifyNoCharacterData(const string_type& ch,
|
||||
const string_type& name)
|
||||
{
|
||||
for(typename string_type::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i)
|
||||
if(!Arabica::XML::is_space(*i))
|
||||
throw SAX::SAXException(name + " element can not contain character data.");
|
||||
throw SAX::SAXException(string_adaptor::asStdString(name) + " element can not contain character data.");
|
||||
} // verifyNoCharacterContent
|
||||
|
||||
} // namespace XSLT
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace XSLT
|
|||
template<class VType>
|
||||
class VariableHandler : public ItemContainerHandler<VType>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
typedef typename VType::string_type string_type;
|
||||
typedef typename VType::string_adaptor string_adaptor;
|
||||
|
@ -38,22 +39,22 @@ protected:
|
|||
const string_type& qName,
|
||||
const SAX::Attributes<string_type, string_adaptor>& atts)
|
||||
{
|
||||
static const ValueRule rules[] = { { "name", true, 0, 0 },
|
||||
{ "select", false, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
static const ValueRule<string_type> rules[] = { { SC::name, true, 0, 0 },
|
||||
{ SC::select, false, 0, 0 },
|
||||
{ string_adaptor::empty_string(), false, 0, 0 } };
|
||||
|
||||
|
||||
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
|
||||
|
||||
const string_type& select = atts.getValue("select");
|
||||
const string_type& select = atts.getValue(SC::select);
|
||||
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> xpath;
|
||||
if(select != "")
|
||||
if(select != string_adaptor::empty_string())
|
||||
{
|
||||
xpath = baseT::context().xpath_expression(select);
|
||||
has_select_ = true;
|
||||
} // if ...
|
||||
|
||||
string_type name = baseT::context().processInternalQName(attrs["name"]).clarkName();
|
||||
string_type name = baseT::context().processInternalQName(attrs[SC::name]).clarkName();
|
||||
return new VType(name, xpath, precedence_);
|
||||
} // createContainer
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
{
|
||||
typename std::map<string_type, string_type>::const_iterator ns = namespaces_.find(qn.prefix);
|
||||
if(ns == namespaces_.end())
|
||||
throw SAX::SAXException("xsl:attribute Runtime Error - Undeclared prefix " + qn.prefix);
|
||||
throw SAX::SAXException("xsl:attribute Runtime Error - Undeclared prefix " + string_adaptor::asStdString(qn.prefix));
|
||||
namesp = ns->second;
|
||||
} // if(!qn.prefix.empty())
|
||||
} // if ...
|
||||
|
|
|
@ -25,6 +25,7 @@ class CompilationContext :
|
|||
{
|
||||
private:
|
||||
typedef Arabica::XPath::DefaultVariableCompileTimeResolver<string_type, string_adaptor> CTVariableResolverT;
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
typedef StylesheetParser<string_type, string_adaptor> StylesheetParserT;
|
||||
|
@ -168,8 +169,8 @@ public:
|
|||
|
||||
string_type autoNamespacePrefix() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "auto-ns" << autoNs_++;
|
||||
std::basic_ostringstream<typename string_adaptor::value_type> ss;
|
||||
ss << SC::auto_ns << autoNs_++;
|
||||
return ss.str();
|
||||
} // autoNamespacePrefix
|
||||
|
||||
|
@ -207,31 +208,31 @@ private:
|
|||
return new UndefinedFunction<string_type, string_adaptor>(namespace_uri, name, argExprs);
|
||||
|
||||
// document
|
||||
if(name == "document")
|
||||
if(name == DocumentFunction<string_type, string_adaptor>::name())
|
||||
return new DocumentFunction<string_type, string_adaptor>(parser_.currentBase(), argExprs);
|
||||
// key
|
||||
if(name == "key")
|
||||
if(name == KeyFunction<string_type, string_adaptor>::name())
|
||||
return new KeyFunction<string_type, string_adaptor>(stylesheet_.keys(), parser_.inScopeNamespaces(), argExprs);
|
||||
// format-number
|
||||
// current
|
||||
if((name == "current") && (current_allowed_))
|
||||
if((name == CurrentFunction<string_type, string_adaptor>::name()) && (current_allowed_))
|
||||
return new CurrentFunction<string_type, string_adaptor>(argExprs);
|
||||
// unparsed-entity-uri
|
||||
//if(name == "unparsed-entity-uri")
|
||||
// return new UnparsedEntityUriFunction(argExprs);
|
||||
if(name == UnparsedEntityUriFunction<string_type, string_adaptor>::name())
|
||||
return new UnparsedEntityUriFunction<string_type, string_adaptor>(argExprs);
|
||||
// generate-id
|
||||
if(name == "generate-id")
|
||||
if(name == GenerateIdFunction<string_type, string_adaptor>::name())
|
||||
return new GenerateIdFunction<string_type, string_adaptor>(argExprs);
|
||||
if(name == "system-property")
|
||||
if(name == SystemPropertyFunction<string_type, string_adaptor>::name())
|
||||
return new SystemPropertyFunction<string_type, string_adaptor>(argExprs);
|
||||
// element-available
|
||||
if(name == "element-available")
|
||||
if(name == ElementAvailableFunction<string_type, string_adaptor>::name())
|
||||
{
|
||||
std::vector<std::pair<string_type, string_type> > dummy;
|
||||
return new ElementAvailableFunction<string_type, string_adaptor>(dummy, parser_.inScopeNamespaces(), argExprs);
|
||||
}
|
||||
// function-available
|
||||
if(name == "function-available")
|
||||
if(name == FunctionAvailableFunction<string_type, string_adaptor>::name())
|
||||
return new FunctionAvailableFunction<string_type, string_adaptor>(validNames(), parser_.inScopeNamespaces(), argExprs);
|
||||
|
||||
return 0;
|
||||
|
@ -239,14 +240,21 @@ private:
|
|||
|
||||
virtual std::vector<std::pair<string_type, string_type> > validNames() const
|
||||
{
|
||||
static const char* functionNames[] = { "document", "key", /* format-number, */ "current",
|
||||
/* unparsed-entity-uri, */ "generate-id", "system-property",
|
||||
/* element-available, */ "function-available", 0 };
|
||||
static string_type functionNames[] = { DocumentFunction<string_type, string_adaptor>::name(),
|
||||
KeyFunction<string_type, string_adaptor>::name(),
|
||||
/* format-number, */
|
||||
CurrentFunction<string_type, string_adaptor>::name(),
|
||||
UnparsedEntityUriFunction<string_type, string_adaptor>::name(),
|
||||
GenerateIdFunction<string_type, string_adaptor>::name(),
|
||||
SystemPropertyFunction<string_type, string_adaptor>::name(),
|
||||
ElementAvailableFunction<string_type, string_adaptor>::name(),
|
||||
FunctionAvailableFunction<string_type, string_adaptor>::name(),
|
||||
string_adaptor::empty_string() };
|
||||
|
||||
std::vector<std::pair<string_type,string_type> > names;
|
||||
|
||||
for(int i = 0; functionNames[i] != 0; ++i)
|
||||
names.push_back(std::make_pair("", functionNames[i]));
|
||||
for(int i = 0; functionNames[i] != string_adaptor::empty_string(); ++i)
|
||||
names.push_back(std::make_pair(string_adaptor::empty_string(), functionNames[i]));
|
||||
|
||||
return names;
|
||||
} // validNames
|
||||
|
|
|
@ -29,8 +29,8 @@ public:
|
|||
typedef DOM::NodeList<string_type, string_adaptor> DOMNodeList;
|
||||
|
||||
CompiledStylesheet() :
|
||||
output_(new StreamSink<string_type, string_adaptor>(std::cout)),
|
||||
error_output_(&std::cerr)
|
||||
output_(new StreamSink<string_type, string_adaptor>(std::wcout)),
|
||||
error_output_(&std::wcerr)
|
||||
{
|
||||
} // CompiledStylesheet
|
||||
|
||||
|
@ -67,7 +67,7 @@ public:
|
|||
output_.reset(sink);
|
||||
} // set_output
|
||||
|
||||
virtual void set_error_output(std::ostream& os)
|
||||
virtual void set_error_output(std::basic_ostream<typename string_adaptor::value_type>& os)
|
||||
{
|
||||
error_output_ = &os;
|
||||
} // set_error_output
|
||||
|
@ -91,7 +91,7 @@ public:
|
|||
|
||||
// go!
|
||||
output_.get().asOutput().start_document(output_settings_, output_cdata_elements_);
|
||||
applyTemplates(ns, context, "");
|
||||
applyTemplates(ns, context, string_adaptor::empty_string());
|
||||
output_.get().asOutput().end_document();
|
||||
} // execute
|
||||
|
||||
|
@ -121,7 +121,7 @@ public:
|
|||
|
||||
if(existing_precedence == templat->precedence())
|
||||
throw SAX::SAXException("Template named '" +
|
||||
templat->name() +
|
||||
string_adaptor::asStdString(templat->name()) +
|
||||
"' already defined");
|
||||
} // if ...
|
||||
|
||||
|
@ -196,8 +196,8 @@ public:
|
|||
if(t == named_templates_.end())
|
||||
{
|
||||
std::cerr << "No template named '";
|
||||
std::cerr << name << "'. I should be a compile-time error!" << std::endl;
|
||||
throw SAX::SAXException("No template named " + name + ". I should be a compile-time error. Sorry!");
|
||||
std::cerr << string_adaptor::asStdString(name) << "'. I should be a compile-time error!" << std::endl;
|
||||
throw SAX::SAXException("No template named " + string_adaptor::asStdString(name) + ". I should be a compile-time error. Sorry!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ private:
|
|||
|
||||
void set_parameter(const string_type& name, Value value)
|
||||
{
|
||||
params_.push_back(new TopLevelParam<string_type, string_adaptor>("", name, value));
|
||||
params_.push_back(new TopLevelParam<string_type, string_adaptor>(string_adaptor::empty_string(), name, value));
|
||||
} // set_parameter
|
||||
|
||||
void set_parameter(const string_type& namespace_uri, const string_type& name, Value value)
|
||||
|
@ -343,7 +343,7 @@ private:
|
|||
typename Output<string_type, string_adaptor>::Settings output_settings_;
|
||||
typename Output<string_type, string_adaptor>::CDATAElements output_cdata_elements_;
|
||||
SinkHolder<string_type, string_adaptor> output_;
|
||||
mutable std::ostream* error_output_;
|
||||
mutable std::basic_ostream<typename string_adaptor::value_type>* error_output_;
|
||||
}; // class CompiledStylesheet
|
||||
|
||||
} // namespace XSLT
|
||||
|
|
|
@ -11,11 +11,12 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class Copy_base : public ItemContainer<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
protected:
|
||||
Copy_base()
|
||||
{
|
||||
Arabica::XPath::XPath<string_type, string_adaptor> compiler;
|
||||
namespace_select_ = compiler.compile("namespace::node()");
|
||||
namespace_select_ = compiler.compile(SC::namespace_xpath);
|
||||
} // Copy_base
|
||||
|
||||
virtual ~Copy_base() { }
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
QName<string_type, string_adaptor> qn = QName<string_type, string_adaptor>::create(name);
|
||||
typename std::map<string_type, string_type>::const_iterator ns = namespaces_.find(qn.prefix);
|
||||
if(ns == namespaces_.end())
|
||||
throw SAX::SAXException("xsl:element Runtime Error - Undeclared prefix " + qn.prefix);
|
||||
throw SAX::SAXException("xsl:element Runtime Error - Undeclared prefix " + string_adaptor::asStdString(qn.prefix));
|
||||
namesp = ns->second;
|
||||
} // if ...
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class ExecutionContext
|
|||
public:
|
||||
ExecutionContext(const CompiledStylesheet<string_type, string_adaptor>& stylesheet,
|
||||
Sink<string_type, string_adaptor>& output,
|
||||
std::ostream& error_output) :
|
||||
std::basic_ostream<typename string_adaptor::value_type>& error_output) :
|
||||
stylesheet_(stylesheet),
|
||||
sink_(output.asOutput()),
|
||||
message_sink_(error_output),
|
||||
|
|
|
@ -25,6 +25,12 @@ class DocumentFunction : public Arabica::XPath::NodeSetXPathFunction<string_type
|
|||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("document");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
DocumentFunction(const string_type& currentBase,
|
||||
const ArgList& args) :
|
||||
baseT(1, 2, args),
|
||||
|
@ -54,10 +60,9 @@ private:
|
|||
SAX::CatchErrorHandler<string_type, string_adaptor> eh;
|
||||
domParser.setErrorHandler(eh);
|
||||
|
||||
Arabica::io::URI base(baseURI_);
|
||||
Arabica::io::URI absolute(base, location);
|
||||
|
||||
SAX::InputSource<string_type, string_adaptor> is(absolute.as_string());
|
||||
Arabica::io::URI base(string_adaptor::asStdString(baseURI_));
|
||||
Arabica::io::URI absolute(base, string_adaptor::asStdString(location));
|
||||
SAX::InputSource<string_type, string_adaptor> is(string_adaptor::construct_from_utf8(absolute.as_string().c_str()));
|
||||
domParser.parse(is);
|
||||
|
||||
if(!eh.errorsReported())
|
||||
|
@ -83,6 +88,12 @@ class KeyFunction : public Arabica::XPath::NodeSetXPathFunction<string_type, str
|
|||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
typedef XML::QualifiedName<string_type, string_adaptor> QualifiedName;
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("key");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
KeyFunction(const DeclaredKeys<string_type, string_adaptor>& keys,
|
||||
const std::map<string_type, string_type>& inscopeNamespaces,
|
||||
const ArgList& args) :
|
||||
|
@ -139,6 +150,12 @@ class CurrentFunction : public Arabica::XPath::NodeSetXPathFunction<string_type,
|
|||
typedef Arabica::XPath::ExecutionContext<string_type, string_adaptor> XPathExecutionContext;
|
||||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("current");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
CurrentFunction(const ArgList& args) :
|
||||
baseT(0, 0, args) { }
|
||||
|
||||
|
@ -163,6 +180,12 @@ class UnparsedEntityUriFunction : public Arabica::XPath::StringXPathFunction<str
|
|||
typedef Arabica::XPath::ExecutionContext<string_type, string_adaptor> XPathExecutionContext;
|
||||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("unparsed-entity-uri");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
UnparsedEntityUriFunction(const ArgList& args) :
|
||||
baseT(1, 1, args) { }
|
||||
|
||||
|
@ -171,7 +194,7 @@ protected:
|
|||
const XPathExecutionContext& /* executionContext */) const
|
||||
{
|
||||
// This is a minimal, but I think conformant, implementation
|
||||
return "";
|
||||
return string_adaptor::empty_string();
|
||||
} // evaluate
|
||||
}; // UnparsedEntityUri
|
||||
|
||||
|
@ -187,6 +210,12 @@ class GenerateIdFunction : public Arabica::XPath::StringXPathFunction<string_typ
|
|||
typedef Arabica::XPath::ExecutionContext<string_type, string_adaptor> XPathExecutionContext;
|
||||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("generate-id");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
GenerateIdFunction(const ArgList& args) :
|
||||
baseT(0, 1, args) { }
|
||||
|
||||
|
@ -201,11 +230,11 @@ protected:
|
|||
{
|
||||
NodeSet ns = baseT::argAsNodeSet(0, context, executionContext);
|
||||
if(ns.size() == 0)
|
||||
return "";
|
||||
return string_adaptor::empty_string();
|
||||
node = ns.top();
|
||||
} // if ...
|
||||
|
||||
std::ostringstream os;
|
||||
std::basic_ostringstream<typename string_adaptor::value_type> os;
|
||||
os << node.underlying_impl();
|
||||
return os.str();
|
||||
} // doEvaluate
|
||||
|
@ -222,6 +251,12 @@ class SystemPropertyFunction : public Arabica::XPath::StringXPathFunction<string
|
|||
typedef Arabica::XPath::ExecutionContext<string_type, string_adaptor> XPathExecutionContext;
|
||||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("system-property");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
SystemPropertyFunction (const ArgList& args) :
|
||||
baseT(1, 1, args) { }
|
||||
|
||||
|
@ -229,15 +264,17 @@ protected:
|
|||
virtual string_type doEvaluate(const DOMNode& context,
|
||||
const XPathExecutionContext& executionContext) const
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
string_type property = baseT::argAsString(0, context, executionContext);
|
||||
string_type result;
|
||||
if(property == "xsl:version")
|
||||
return "1.0";
|
||||
if(property == "xsl:vendor")
|
||||
return "Jez Higgins, Jez UK Ltd";
|
||||
else if(property == "xsl:vendor-url")
|
||||
return "http://www.jezuk.co.uk/arabica";
|
||||
return "";
|
||||
if(property == SC::version_property)
|
||||
return SC::Version;
|
||||
if(property == SC::vendor_property)
|
||||
return SC::Vendor;
|
||||
else if(property == SC::vendor_url_property)
|
||||
return SC::VendorUrl;
|
||||
return string_adaptor::empty_string();
|
||||
} // evaluate
|
||||
}; // SystemPropertyFunction
|
||||
|
||||
|
@ -253,6 +290,12 @@ class ElementAvailableFunction : public Arabica::XPath::BooleanXPathFunction<str
|
|||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
typedef XML::QualifiedName<string_type, string_adaptor> QualifiedName;
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("element_available");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
ElementAvailableFunction(const std::vector<std::pair<string_type, string_type> >& names,
|
||||
const std::map<string_type, string_type>& inscopeNamespaces,
|
||||
const ArgList& args) :
|
||||
|
@ -266,20 +309,36 @@ protected:
|
|||
virtual bool doEvaluate(const DOMNode& context,
|
||||
const XPathExecutionContext& executionContext) const
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
const string_type functionName = baseT::argAsString(0, context, executionContext);
|
||||
const QualifiedName expandedName = QualifiedName::parseQName(functionName, true, namespaces_);
|
||||
|
||||
if((expandedName.namespaceUri() != StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) &&
|
||||
if((expandedName.namespaceUri() != StylesheetConstant<string_type, string_adaptor>::NamespaceURI) &&
|
||||
(!expandedName.namespaceUri().empty()))
|
||||
return false;
|
||||
|
||||
static const char* XSLTNames[] = { "apply-imports", "apply-templates", "attributes",
|
||||
"call-template", "choose", "comment", "copy",
|
||||
"copy-of", "element", "fallback", "for-each",
|
||||
"if", "message", "number", "processing-instruction",
|
||||
"text", "value-of", "variable", 0 };
|
||||
static string_type XSLTNames[] = { SC::apply_imports,
|
||||
SC::apply_templates,
|
||||
SC::attribute,
|
||||
SC::call_template,
|
||||
SC::choose,
|
||||
SC::comment,
|
||||
SC::copy,
|
||||
SC::copy_of,
|
||||
SC::element,
|
||||
SC::fallback,
|
||||
SC::for_each,
|
||||
SC::if_,
|
||||
SC::message,
|
||||
SC::number,
|
||||
SC::processing_instruction,
|
||||
SC::text,
|
||||
SC::value_of,
|
||||
SC::variable,
|
||||
string_adaptor::empty_string() };
|
||||
|
||||
for(int i = 0; XSLTNames[i] != 0; ++i)
|
||||
for(int i = 0; XSLTNames[i] != string_adaptor::empty_string(); ++i)
|
||||
if(expandedName.localName() == XSLTNames[i])
|
||||
return true;
|
||||
|
||||
|
@ -303,6 +362,12 @@ class FunctionAvailableFunction : public Arabica::XPath::BooleanXPathFunction<st
|
|||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
typedef XML::QualifiedName<string_type, string_adaptor> QualifiedName;
|
||||
public:
|
||||
static const string_type& name()
|
||||
{
|
||||
static const string_type n = string_adaptor::construct_from_utf8("function-available");
|
||||
return n;
|
||||
} // name
|
||||
|
||||
FunctionAvailableFunction(const std::vector<std::pair<string_type, string_type> >& names,
|
||||
const std::map<string_type, string_type>& inscopeNamespaces,
|
||||
const ArgList& args) :
|
||||
|
@ -347,11 +412,13 @@ public:
|
|||
const ArgList& args) :
|
||||
baseT(-1, -1, args)
|
||||
{
|
||||
typedef Arabica::text::Unicode<string_adaptor::value_type> UnicodeT;
|
||||
|
||||
if(!namespace_uri.empty())
|
||||
{
|
||||
error_ += "{";
|
||||
error_ += UnicodeT::LEFT_SQUARE_BRACKET;
|
||||
error_ += namespace_uri;
|
||||
error_ += "}";
|
||||
error_ += UnicodeT::RIGHT_SQUARE_BRACKET;
|
||||
} // if ..
|
||||
|
||||
error_ += name;
|
||||
|
@ -360,7 +427,7 @@ public:
|
|||
protected:
|
||||
virtual bool doEvaluate(const DOMNode&, const XPathExecutionContext&) const
|
||||
{
|
||||
throw Arabica::XPath::UndefinedFunctionException(error_);
|
||||
throw Arabica::XPath::UndefinedFunctionException(string_adaptor::asStdString(error_));
|
||||
} // doEvaluate
|
||||
|
||||
string_type error_;
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
{
|
||||
const KeysIterator k = keys_.find(name);
|
||||
if(k == keys_.end())
|
||||
throw SAX::SAXException("No key named '" + name + "' has been defined.");
|
||||
throw SAX::SAXException("No key named '" + string_adaptor::asStdString(name) + "' has been defined.");
|
||||
|
||||
if(k->second.size() == 1)
|
||||
return k->second[0]->lookup(id, context);
|
||||
|
|
|
@ -4,14 +4,17 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "handler/xslt_constants.hpp"
|
||||
|
||||
namespace Arabica
|
||||
{
|
||||
namespace XSLT
|
||||
{
|
||||
|
||||
template<class string_type>
|
||||
template<class string_type, class string_adaptor>
|
||||
class NamespaceStack
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
typedef std::map<string_type, string_type> Scope;
|
||||
|
||||
|
@ -39,7 +42,7 @@ public:
|
|||
if(findPrefix(namespaceURI) != EMPTY_STRING)
|
||||
return;
|
||||
|
||||
bool remap = (attr && given_prefix.empty()) || (given_prefix == "xmlns");
|
||||
bool remap = (attr && given_prefix.empty()) || (given_prefix == SC::xmlns);
|
||||
|
||||
string_type prefix = !remap ? given_prefix : autoNamespacePrefix();
|
||||
|
||||
|
@ -76,8 +79,8 @@ private:
|
|||
|
||||
string_type autoNamespacePrefix()
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "auto-ns" << autoNs_++;
|
||||
std::basic_ostringstream<typename string_adaptor::value_type> ss;
|
||||
ss << SC::auto_ns << autoNs_++;
|
||||
return ss.str();
|
||||
} // autoNamespacePrefix
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class Output
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
typedef std::map<string_type, string_type> Settings;
|
||||
typedef std::set<QName<string_type, string_adaptor> > CDATAElements;
|
||||
|
@ -36,8 +37,8 @@ protected:
|
|||
public:
|
||||
void start_document(const Settings& settings, const CDATAElements& cdataElements)
|
||||
{
|
||||
typename Settings::const_iterator method = settings.find("method");
|
||||
text_mode_ = (method != settings.end() && method->second == "text");
|
||||
typename Settings::const_iterator method = settings.find(SC::method);
|
||||
text_mode_ = (method != settings.end() && method->second == SC::text);
|
||||
if(text_mode_)
|
||||
do_disableOutputEscaping(true);
|
||||
|
||||
|
@ -94,7 +95,7 @@ public:
|
|||
if(!text_mode_)
|
||||
{
|
||||
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
||||
do_end_element((!mapped_prefix.empty()) ? mapped_prefix + ':' + localName : localName, namespaceURI);
|
||||
do_end_element((!mapped_prefix.empty()) ? mapped_prefix + SC::COLON + localName : localName, namespaceURI);
|
||||
element_stack_.pop();
|
||||
} // end_element
|
||||
|
||||
|
@ -114,7 +115,7 @@ public:
|
|||
|
||||
if(!pending_element_)
|
||||
{
|
||||
warning("WARNING: Cannot write attribute, no open element");
|
||||
warning(string_adaptor::construct_from_utf8("WARNING: Cannot write attribute, no open element"));
|
||||
return;
|
||||
} // if ...
|
||||
|
||||
|
@ -122,13 +123,13 @@ public:
|
|||
namespaceStack_.declareNamespace(prefix, namespaceURI, true);
|
||||
|
||||
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
|
||||
string_type qName = (!mapped_prefix.empty()) ? mapped_prefix + ':' + localName : localName;
|
||||
string_type qName = (!mapped_prefix.empty()) ? mapped_prefix + SC::COLON + localName : localName;
|
||||
|
||||
atts_.addOrReplaceAttribute(namespaceURI,
|
||||
localName,
|
||||
qName,
|
||||
"",
|
||||
"");
|
||||
string_adaptor::empty_string(),
|
||||
string_adaptor::empty_string());
|
||||
pending_attribute_ = atts_.getIndex(qName);
|
||||
} // start_attribute
|
||||
|
||||
|
@ -152,11 +153,11 @@ public:
|
|||
{
|
||||
if(!pending_element_)
|
||||
{
|
||||
warning("WARNING: Cannot write attribute, no open element");
|
||||
warning(string_adaptor::construct_from_utf8("WARNING: Cannot write attribute, no open element"));
|
||||
return;
|
||||
} // if ...
|
||||
|
||||
atts_.addAttribute(uri, localName, qName, "", value);
|
||||
atts_.addAttribute(uri, localName, qName, string_adaptor::empty_string(), value);
|
||||
} // add_attribute
|
||||
|
||||
void characters(const string_type& ch)
|
||||
|
@ -203,9 +204,9 @@ public:
|
|||
|
||||
if(!text_mode_)
|
||||
{
|
||||
string_type comment = escape(buffer_.str(), "--", "- -");
|
||||
if(comment.length() && *(comment.rbegin()) == '-')
|
||||
comment.append(" ");
|
||||
string_type comment = escape(buffer_.str(), SC::double_hyphen, SC::escaped_double_hyphen);
|
||||
if(comment.length() && *(comment.rbegin()) == SC::HYPHEN_MINUS)
|
||||
comment += SC::SPACE;
|
||||
do_comment(comment);
|
||||
} // if ...
|
||||
} // end_comment
|
||||
|
@ -227,7 +228,7 @@ public:
|
|||
|
||||
if(!text_mode_)
|
||||
{
|
||||
string_type data = escape(buffer_.str(), "?>", "? >");
|
||||
string_type data = escape(buffer_.str(), SC::PIEnd, SC::escaped_pi_end);
|
||||
do_processing_instruction(target_, data);
|
||||
} // if ...
|
||||
} // end_processing_instruction
|
||||
|
@ -276,7 +277,7 @@ private:
|
|||
if(is_buf)
|
||||
return true;
|
||||
|
||||
buffer_.str("");
|
||||
buffer_.str(string_adaptor::empty_string());
|
||||
return false;
|
||||
} // push_buffering
|
||||
|
||||
|
@ -284,7 +285,7 @@ private:
|
|||
{
|
||||
if(!buffering_)
|
||||
return false;
|
||||
warning("WARNING: non-text ignored when creating processing instruction, comment or attribute");
|
||||
warning(string_adaptor::construct_from_utf8("WARNING: non-text ignored when creating processing instruction, comment or attribute"));
|
||||
return true;
|
||||
} // is_buffering
|
||||
|
||||
|
@ -343,16 +344,16 @@ private:
|
|||
|
||||
void addNamespaceDeclarations()
|
||||
{
|
||||
for(typename NamespaceStack<string_type>::Scope::const_iterator n = namespaceStack_.begin(), ne = namespaceStack_.end(); n != ne; ++n)
|
||||
for(typename NamespaceStack<string_type, string_adaptor>::Scope::const_iterator n = namespaceStack_.begin(), ne = namespaceStack_.end(); n != ne; ++n)
|
||||
{
|
||||
if(n->first == "xml")
|
||||
if(n->first == SC::xml)
|
||||
continue;
|
||||
|
||||
string_type qName = (n->first.empty()) ? "xmlns" : "xmlns:" + n->first;
|
||||
atts_.addAttribute("http://www.w3.org/2000/xmlns",
|
||||
string_type qName = (n->first.empty()) ? SC::xmlns : SC::xmlns_colon + n->first;
|
||||
atts_.addAttribute(SC::xmlns_uri,
|
||||
n->first,
|
||||
qName,
|
||||
"",
|
||||
string_adaptor::empty_string(),
|
||||
n->second);
|
||||
}
|
||||
} // addNamespaceDeclarations
|
||||
|
@ -360,7 +361,7 @@ private:
|
|||
void warning(const string_type& warning_message)
|
||||
{
|
||||
warning_sink_->characters(warning_message);
|
||||
warning_sink_->characters("\n");
|
||||
warning_sink_->characters(SC::newline);
|
||||
} // warning
|
||||
|
||||
int buffering_;
|
||||
|
@ -373,8 +374,8 @@ private:
|
|||
std::stack<QName<string_type, string_adaptor> > element_stack_;
|
||||
string_type target_;
|
||||
SAX::AttributesImpl<string_type, string_adaptor> atts_;
|
||||
std::stringstream buffer_;
|
||||
NamespaceStack<string_type> namespaceStack_;
|
||||
std::basic_stringstream<typename string_adaptor::value_type> buffer_;
|
||||
NamespaceStack<string_type, string_adaptor> namespaceStack_;
|
||||
}; // class Output
|
||||
|
||||
} // namespace XSLT
|
||||
|
|
|
@ -41,7 +41,7 @@ private:
|
|||
throw SAX::SAXException("xsl:processing-instruction : name attribute must evaluate to a valid name");
|
||||
|
||||
if(!Arabica::XML::is_ncname<string_adaptor>(name))
|
||||
throw SAX::SAXException("xsl:processing-instruction : '" + name + "' is not valid as the name");
|
||||
throw SAX::SAXException("xsl:processing-instruction : '" + string_adaptor::asStdString(name) + "' is not valid as the name");
|
||||
|
||||
if(name.length() != 3)
|
||||
return;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define ARABICA_XSLT_QNAME_HPP
|
||||
|
||||
#include <XML/strings.hpp>
|
||||
#include "handler/xslt_constants.hpp"
|
||||
|
||||
namespace Arabica
|
||||
{
|
||||
|
@ -11,6 +12,8 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
struct QName
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
string_type prefix;
|
||||
string_type localName;
|
||||
string_type namespaceURI;
|
||||
|
@ -22,33 +25,31 @@ struct QName
|
|||
prefix(p),
|
||||
localName(lN),
|
||||
namespaceURI(uri),
|
||||
qname(p.empty() ? lN : (p + ":" + lN))
|
||||
qname(p.empty() ? lN : (p + SC::COLON + lN))
|
||||
{
|
||||
} // QName
|
||||
|
||||
static QName create(const XML::QualifiedName<string_type>& qName)
|
||||
{
|
||||
if(qName.prefix().length() && qName.namespaceUri().empty())
|
||||
throw SAX::SAXException("Prefix " + qName.prefix() + " is not declared.");
|
||||
throw SAX::SAXException("Prefix " + string_adaptor::asStdString(qName.prefix()) + " is not declared.");
|
||||
return QName(qName.prefix(), qName.localName(), qName.namespaceUri());
|
||||
} // create
|
||||
|
||||
static QName create(const string_type& qName)
|
||||
{
|
||||
return create(qName, "");
|
||||
return create(qName, string_adaptor::empty_string());
|
||||
} // create
|
||||
|
||||
static QName create(const string_type& qName, const string_type& namespaceURI)
|
||||
{
|
||||
if(!Arabica::XML::is_qname<string_adaptor>(qName))
|
||||
throw SAX::SAXException("Bad name : '" + qName + "'");
|
||||
|
||||
static char COLON = Arabica::text::Unicode<char>::COLON;
|
||||
throw SAX::SAXException("Bad name : '" + string_adaptor::asStdString(qName) + "'");
|
||||
|
||||
string_type prefix;
|
||||
string_type localName;
|
||||
|
||||
size_t colon = qName.find(COLON);
|
||||
size_t colon = qName.find(SC::COLON);
|
||||
|
||||
if(colon == string_type::npos)
|
||||
localName = qName;
|
||||
|
|
|
@ -82,8 +82,10 @@ private:
|
|||
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
|
||||
class StreamSink : public Sink<string_type, string_adaptor>, private Output<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
|
||||
public:
|
||||
StreamSink(std::ostream& stream) :
|
||||
StreamSink(std::basic_ostream<typename string_adaptor::value_type>& stream) :
|
||||
stream_(stream),
|
||||
disable_output_escaping_(false),
|
||||
in_cdata_(false),
|
||||
|
@ -120,7 +122,7 @@ protected:
|
|||
{
|
||||
seen_root_ = false;
|
||||
settings_ = settings;
|
||||
if(setting("indent") == "yes")
|
||||
if(setting(SC::indent) == SC::yes)
|
||||
indent_ = 0;
|
||||
} // do_start_document
|
||||
|
||||
|
@ -144,7 +146,7 @@ protected:
|
|||
{
|
||||
stream_ << ' ' << atts.getQName(a) << '=' << '\"';
|
||||
string_type ch = atts.getValue(a);
|
||||
std::for_each(ch.begin(), ch.end(), Arabica::XML::attribute_escaper<char>(stream_));
|
||||
std::for_each(ch.begin(), ch.end(), Arabica::XML::attribute_escaper<typename string_adaptor::value_type>(stream_));
|
||||
stream_ << '\"';
|
||||
}
|
||||
empty_ = true;
|
||||
|
@ -154,7 +156,7 @@ protected:
|
|||
const string_type& /* namespaceURI */)
|
||||
{
|
||||
if(!seen_root_)
|
||||
do_decl("");
|
||||
do_decl(string_adaptor::empty_string());
|
||||
|
||||
preoutdent(empty_);
|
||||
|
||||
|
@ -173,10 +175,10 @@ protected:
|
|||
close_element_if_empty();
|
||||
|
||||
if(!disable_output_escaping_ && !in_cdata_)
|
||||
std::for_each(ch.begin(), ch.end(), Arabica::XML::text_escaper<char>(stream_));
|
||||
std::for_each(ch.begin(), ch.end(), Arabica::XML::text_escaper<typename string_adaptor::value_type>(stream_));
|
||||
else if(in_cdata_)
|
||||
{
|
||||
size_t breakAt = ch.find("]]>");
|
||||
size_t breakAt = ch.find(SC::CDATAEnd);
|
||||
if(breakAt == string_type::npos)
|
||||
{
|
||||
stream_ << ch;
|
||||
|
@ -190,7 +192,7 @@ protected:
|
|||
do_end_CDATA();
|
||||
start = breakAt;
|
||||
do_start_CDATA();
|
||||
breakAt = ch.find("]]>", breakAt);
|
||||
breakAt = ch.find(SC::CDATAEnd, breakAt);
|
||||
}
|
||||
while(breakAt != string_type::npos);
|
||||
stream_ << ch.substr(start);
|
||||
|
@ -204,22 +206,22 @@ protected:
|
|||
close_element_if_empty();
|
||||
|
||||
in_cdata_ = true;
|
||||
stream_ << "<![CDATA[";
|
||||
stream_ << SC::CDATAStart;
|
||||
} // do_start_CDATA
|
||||
|
||||
void do_end_CDATA()
|
||||
{
|
||||
in_cdata_ = false;
|
||||
stream_ << "]]>";
|
||||
stream_ << SC::CDATAEnd;
|
||||
} // do_end_CDATA
|
||||
|
||||
void do_comment(const string_type& ch)
|
||||
{
|
||||
close_element_if_empty();
|
||||
|
||||
stream_ << "<!--"
|
||||
stream_ << SC::CommentStart
|
||||
<< ch
|
||||
<< "-->";
|
||||
<< SC::CommentEnd;
|
||||
} // do_comment
|
||||
|
||||
void do_processing_instruction(const string_type& target,
|
||||
|
@ -227,11 +229,11 @@ protected:
|
|||
{
|
||||
close_element_if_empty();
|
||||
|
||||
stream_ << "<?"
|
||||
stream_ << SC::PIStart
|
||||
<< target
|
||||
<< " "
|
||||
<< data
|
||||
<< "?>";
|
||||
<< SC::PIEnd;
|
||||
} // do_processing_instruction
|
||||
|
||||
void do_disableOutputEscaping(bool disable) { disable_output_escaping_ = disable; }
|
||||
|
@ -248,7 +250,7 @@ private:
|
|||
}
|
||||
|
||||
if(!seen_root_)
|
||||
do_decl("");
|
||||
do_decl(string_adaptor::empty_string());
|
||||
} // close_element_if_empty
|
||||
|
||||
void indent()
|
||||
|
@ -287,17 +289,17 @@ private:
|
|||
|
||||
void do_decl(const string_type& qName)
|
||||
{
|
||||
if((setting("method") == "text") || (setting("omit-xml-declaration") == "yes"))
|
||||
if((setting(SC::method) == SC::text) || (setting(SC::omit_xml_declaration) == SC::yes))
|
||||
return;
|
||||
|
||||
{
|
||||
string_type version = setting("version");
|
||||
string_type version = setting(SC::version);
|
||||
if(version.empty())
|
||||
version = "1.0";
|
||||
version = SC::Version;
|
||||
stream_ << "<?xml version=\"" << version << "\"";
|
||||
}
|
||||
{
|
||||
string_type s = setting("standalone");
|
||||
string_type s = setting(SC::standalone);
|
||||
if(!s.empty())
|
||||
stream_ << " standalone=\"" << s << "\"";
|
||||
}
|
||||
|
@ -305,8 +307,8 @@ private:
|
|||
|
||||
if(!qName.empty())
|
||||
{
|
||||
string_type pub = setting("doctype-public");
|
||||
string_type sys = setting("doctype-system");
|
||||
string_type pub = setting(SC::doctype_public);
|
||||
string_type sys = setting(SC::doctype_system);
|
||||
|
||||
if(!sys.empty())
|
||||
{
|
||||
|
@ -324,11 +326,11 @@ private:
|
|||
{
|
||||
typename Settings::const_iterator i = settings_.find(name);
|
||||
if(i == settings_.end())
|
||||
return "";
|
||||
return string_adaptor::empty_string();
|
||||
return i->second;
|
||||
} // setting
|
||||
|
||||
std::ostream& stream_;
|
||||
std::basic_ostream<typename string_adaptor::value_type>& stream_;
|
||||
bool disable_output_escaping_;
|
||||
bool in_cdata_;
|
||||
bool empty_;
|
||||
|
@ -363,9 +365,9 @@ protected:
|
|||
|
||||
void do_start_document(const Settings& settings)
|
||||
{
|
||||
typename Settings::const_iterator i = settings.find("indent");
|
||||
typename Settings::const_iterator i = settings.find(SC::indent);
|
||||
if((i != settings.end()) &&
|
||||
(i->second == "yes"))
|
||||
(i->second == SC::yes))
|
||||
indent_ = 0;
|
||||
} // do_start_document
|
||||
|
||||
|
@ -437,7 +439,7 @@ private:
|
|||
return document_;
|
||||
|
||||
DOM::DOMImplementation<string_type, string_adaptor> di = SimpleDOM::DOMImplementation<string_type, string_adaptor>::getDOMImplementation();
|
||||
document_ = di.createDocument("", "", 0);
|
||||
document_ = di.createDocument(string_adaptor::empty_string(), string_adaptor::empty_string(), 0);
|
||||
return document_;
|
||||
} // document
|
||||
|
||||
|
@ -475,7 +477,7 @@ private:
|
|||
return;
|
||||
|
||||
if(out_again_)
|
||||
do_characters("\n");
|
||||
do_characters(SC::newline);
|
||||
|
||||
indent_ -= 2;
|
||||
out_again_ = true;
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class Sort
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
typedef Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> XPathExpressionPtr;
|
||||
typedef DOM::Node<string_type, string_adaptor> DOMNode;
|
||||
|
@ -41,20 +42,20 @@ public:
|
|||
const string_type order = order_->evaluateAsString(node, context_->xpathContext());
|
||||
const string_type caseorder = caseorder_->evaluateAsString(node, context_->xpathContext());
|
||||
|
||||
static const char* allowed_datatypes[] = { "text", "number", 0 };
|
||||
static const char* allowed_orders[] = { "ascending", "descending", 0 };
|
||||
static const char* allowed_case_orders[] = { "upper-first", "lower-first", 0 };
|
||||
validateValues<string_type>("xsl:sort", "data-type", datatype, allowed_datatypes);
|
||||
validateValues<string_type>("xsl:sort", "order", order, allowed_orders);
|
||||
validateValues<string_type>("xsl:sort", "case-order", caseorder, allowed_case_orders);
|
||||
static string_type allowed_datatypes[] = { SC::text, SC::number, string_adaptor::empty_string() };
|
||||
static string_type allowed_orders[] = { SC::ascending, SC::descending, string_adaptor::empty_string() };
|
||||
static string_type allowed_case_orders[] = { SC::upper_first, SC::lower_first, string_adaptor::empty_string() };
|
||||
validateValues<string_type, string_adaptor>(SC::sort, SC::data_type, datatype, allowed_datatypes);
|
||||
validateValues<string_type, string_adaptor>(SC::sort, SC::order, order, allowed_orders);
|
||||
validateValues<string_type, string_adaptor>(SC::sort, SC::case_order, caseorder, allowed_case_orders);
|
||||
|
||||
if(datatype == "number")
|
||||
if(order == "ascending")
|
||||
if(datatype == SC::number)
|
||||
if(order == SC::ascending)
|
||||
sort_fn_ = &Sort::numberAscending;
|
||||
else
|
||||
sort_fn_ = &Sort::numberDescending;
|
||||
else
|
||||
if(order == "ascending")
|
||||
if(order == SC::ascending)
|
||||
sort_fn_ = &Sort::stringAscending;
|
||||
else
|
||||
sort_fn_ = &Sort::stringDescending;
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
|
||||
virtual void set_output(Sink<string_type, string_adaptor>& sink) = 0;
|
||||
|
||||
virtual void set_error_output(std::ostream& os) = 0;
|
||||
virtual void set_error_output(std::basic_ostream<typename string_adaptor::value_type>& os) = 0;
|
||||
|
||||
virtual void execute(const DOM::Node<string_type, string_adaptor>& initialNode) const = 0;
|
||||
}; // class Stylesheet
|
||||
|
|
|
@ -24,6 +24,7 @@ namespace XSLT
|
|||
template<class string_type, class string_adaptor>
|
||||
class StylesheetHandler : public SAX::DefaultHandler<string_type, string_adaptor>
|
||||
{
|
||||
typedef StylesheetConstant<string_type, string_adaptor> SC;
|
||||
public:
|
||||
typedef string_type stringT;
|
||||
typedef string_adaptor string_adaptorT;
|
||||
|
@ -52,14 +53,14 @@ public:
|
|||
if(top_)
|
||||
{
|
||||
top_ = false;
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
|
||||
if(namespaceURI == SC::NamespaceURI)
|
||||
startStylesheet(namespaceURI, localName, qName, atts);
|
||||
else
|
||||
startLREAsStylesheet(namespaceURI, localName, qName, atts);
|
||||
return;
|
||||
} // if(top_)
|
||||
|
||||
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
|
||||
if(namespaceURI == SC::NamespaceURI)
|
||||
startXSLTElement(namespaceURI, localName, qName, atts);
|
||||
else if(!namespaceURI.empty())
|
||||
startForeignElement(namespaceURI, localName, qName, atts);
|
||||
|
@ -75,7 +76,7 @@ public:
|
|||
|
||||
virtual void characters(const string_type& ch)
|
||||
{
|
||||
verifyNoCharacterData<string_type>(ch, "xsl:stylesheet/xsl:transform");
|
||||
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::stylesheet);
|
||||
} // characters
|
||||
|
||||
virtual void endDocument()
|
||||
|
@ -90,18 +91,18 @@ private:
|
|||
const string_type& qName,
|
||||
const AttributesT& atts)
|
||||
{
|
||||
if(localName != "stylesheet" && localName != "transform")
|
||||
if(localName != SC::stylesheet && localName != SC::transform)
|
||||
throw SAX::SAXException("Top-level element must be 'stylesheet' or 'transform'.");
|
||||
|
||||
static const ValueRule rules[] = { { "version", true, 0, 0 },
|
||||
{ "extension-element-prefixes", false, 0, 0 },
|
||||
{ "exclude-result-prefixes", false, 0, 0 },
|
||||
{ "id", false, 0, 0 },
|
||||
static const ValueRule<string_type> rules[] = { { SC::version, true, 0, 0 },
|
||||
{ SC::extension_element_prefixes, false, 0, 0 },
|
||||
{ SC::exclude_result_prefixes, false, 0, 0 },
|
||||
{ SC::id, false, 0, 0 },
|
||||
{ 0, false, 0, 0 } };
|
||||
std::map<string_type, string_type> attributes = gatherAttributes(qName, atts, rules);
|
||||
if(attributes["version"] != StylesheetConstant<string_type, string_adaptor>::Version())
|
||||
if(attributes[SC::version] != SC::Version)
|
||||
throw SAX::SAXException("I'm only a poor version 1.0 XSLT Transformer.");
|
||||
if(!attributes["extension-element-prefixes"].empty())
|
||||
if(!attributes[SC::extension_element_prefixes].empty())
|
||||
throw SAX::SAXException("Haven't implemented extension-element-prefixes yet");
|
||||
} // startStylesheet
|
||||
|
||||
|
@ -112,8 +113,8 @@ private:
|
|||
{
|
||||
string_type version;
|
||||
for(int a = 0; a != atts.getLength(); ++a)
|
||||
if((StylesheetConstant<string_type, string_adaptor>::NamespaceURI() == atts.getURI(a)) &&
|
||||
("version" == atts.getLocalName(a)))
|
||||
if((SC::NamespaceURI == atts.getURI(a)) &&
|
||||
(SC::version == atts.getLocalName(a)))
|
||||
{
|
||||
version = atts.getValue(a);
|
||||
break;
|
||||
|
@ -121,10 +122,15 @@ private:
|
|||
|
||||
if(version.empty())
|
||||
throw SAX::SAXException("The source file does not look like a stylesheet.");
|
||||
if(version != StylesheetConstant<string_type, string_adaptor>::Version())
|
||||
if(version != SC::Version)
|
||||
throw SAX::SAXException("I'm only a poor version 1.0 XSLT Transformer.");
|
||||
|
||||
Template<string_type, string_adaptor>* lreStylesheet = new Template<string_type, string_adaptor>(context_.xpath_match("/"), "", "", "", context_.precedence());
|
||||
Template<string_type, string_adaptor>* lreStylesheet =
|
||||
new Template<string_type, string_adaptor>(context_.xpath_match(SC::root_xpath),
|
||||
string_adaptor::empty_string(),
|
||||
string_adaptor::empty_string(),
|
||||
string_adaptor::empty_string(),
|
||||
context_.precedence());
|
||||
context_.push(lreStylesheet,
|
||||
new LREStylesheetHandler<string_type, string_adaptor>(context_, lreStylesheet),
|
||||
namespaceURI,
|
||||
|
@ -138,13 +144,13 @@ private:
|
|||
const string_type& qName,
|
||||
const AttributesT& atts)
|
||||
{
|
||||
if((localName == "import") || (localName == "include"))
|
||||
if((localName == SC::import) || (localName == SC::include))
|
||||
{
|
||||
include_stylesheet(namespaceURI, localName, qName, atts);
|
||||
return;
|
||||
} // if ...
|
||||
|
||||
for(const ChildElement<string_type, string_adaptor>* c = allowedChildren; c->name != 0; ++c)
|
||||
for(const ChildElement<string_type, string_adaptor>* c = allowedChildren; c->name != string_adaptor::empty_string(); ++c)
|
||||
if(c->name == localName)
|
||||
{
|
||||
context_.push(0,
|
||||
|
@ -182,7 +188,7 @@ private:
|
|||
|
||||
void oops(const string_type& qName) const
|
||||
{
|
||||
throw SAX::SAXException("xsl:stylesheet does not allow " + qName + " here.");
|
||||
throw SAX::SAXException("xsl:stylesheet does not allow " + string_adaptor::asStdString(qName) + " here.");
|
||||
} // oops
|
||||
|
||||
CompilationContextT& context_;
|
||||
|
@ -196,18 +202,18 @@ private:
|
|||
template<class string_type, class string_adaptor>
|
||||
const ChildElement<string_type, string_adaptor> StylesheetHandler<string_type, string_adaptor>::allowedChildren[] =
|
||||
{
|
||||
{ "attribute-set", CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ "decimal-format", CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ SC::attribute_set, CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ SC::decimal_format, CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
//"import"
|
||||
//"include"
|
||||
{ "key", CreateHandler<KeyHandler<string_type, string_adaptor> >},
|
||||
{ "namespace-alias", CreateHandler<NamespaceAliasHandler<string_type, string_adaptor> >},
|
||||
{ "output", CreateHandler<OutputHandler<string_type, string_adaptor> >},
|
||||
{ "param", CreateHandler<TopLevelVariableHandler<Param<string_type, string_adaptor> > >},
|
||||
{ "preserve-space", CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ "strip-space", CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ "template", CreateHandler<TemplateHandler<string_type, string_adaptor> > },
|
||||
{ "variable", CreateHandler<TopLevelVariableHandler<Variable<string_type, string_adaptor> > > },
|
||||
{ SC::key, CreateHandler<KeyHandler<string_type, string_adaptor> >},
|
||||
{ SC::namespace_alias, CreateHandler<NamespaceAliasHandler<string_type, string_adaptor> >},
|
||||
{ SC::output, CreateHandler<OutputHandler<string_type, string_adaptor> >},
|
||||
{ SC::param, CreateHandler<TopLevelVariableHandler<Param<string_type, string_adaptor> > >},
|
||||
{ SC::preserve_space, CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ SC::strip_space, CreateHandler<NotImplementedYetHandler<string_type, string_adaptor> >},
|
||||
{ SC::template_, CreateHandler<TemplateHandler<string_type, string_adaptor> > },
|
||||
{ SC::variable, CreateHandler<TopLevelVariableHandler<Variable<string_type, string_adaptor> > > },
|
||||
{ 0, 0 }
|
||||
}; // StylesheetHandler::allowedChildren
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ private:
|
|||
void verifyQName(const QualifiedNameT& qName) const
|
||||
{
|
||||
if(qName.has_prefix() && !qName.has_namespaceUri())
|
||||
throw SAX::SAXException("Namespace prefix '" + qName.prefix() + "' is not bound");
|
||||
throw SAX::SAXException("Namespace prefix '" + string_adaptor::asStdString(qName.prefix()) + "' is not bound");
|
||||
} // verifyQName
|
||||
|
||||
TextCoalescerT text_coalescer_;
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
execute_children(node, context);
|
||||
|
||||
if(sink.node() == 0)
|
||||
return StringValue::createValue("");
|
||||
return StringValue::createValue(string_adaptor::empty_string());
|
||||
|
||||
NodeSet nodeset;
|
||||
for(DOMNode n = sink.node().getFirstChild(); n != 0; n = n.getNextSibling())
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
Scope& params = params_.back();
|
||||
|
||||
if(params.find(name) != params.end())
|
||||
throw std::runtime_error("Duplicate parameter name in xsl:with-param - " + name);
|
||||
throw std::runtime_error("Duplicate parameter name in xsl:with-param - " + string_adaptor::asStdString(name));
|
||||
params[name] = param;
|
||||
return name;
|
||||
} // passParam
|
||||
|
@ -127,7 +127,7 @@ public:
|
|||
{
|
||||
const Precedence& current_p = stack[name]->precedence();
|
||||
if(var->precedence() == current_p)
|
||||
throw std::runtime_error("Duplicate variable name : " + name);
|
||||
throw std::runtime_error("Duplicate variable name : " + string_adaptor::asStdString(name));
|
||||
if(current_p.is_descendant(var->precedence()))
|
||||
return;
|
||||
if(current_p > var->precedence())
|
||||
|
@ -157,9 +157,11 @@ public:
|
|||
virtual XPathValue resolveVariable(const string_type& namespace_uri,
|
||||
const string_type& name) const
|
||||
{
|
||||
string_type clarkName = namespace_uri.empty() ? name : "{" + namespace_uri + "}" + name;
|
||||
typedef Arabica::text::Unicode<string_adaptor::value_type> UnicodeT;
|
||||
|
||||
string_type clarkName = namespace_uri.empty() ? name : UnicodeT::LEFT_SQUARE_BRACKET + namespace_uri + UnicodeT::RIGHT_SQUARE_BRACKET + name;
|
||||
if(std::find(resolutionStack_.begin(), resolutionStack_.end(), clarkName) != resolutionStack_.end())
|
||||
throw std::runtime_error("Circular dependency: " + clarkName + " refers to itself directly or indirectly.");
|
||||
throw std::runtime_error("Circular dependency: " + string_adaptor::asStdString(clarkName) + " refers to itself directly or indirectly.");
|
||||
|
||||
resolutionStack_.push_back(clarkName);
|
||||
XPathValue val = lookup(stack_.back(), clarkName);
|
||||
|
@ -170,7 +172,7 @@ public:
|
|||
|
||||
val = lookup(stack_.front(), clarkName); // try our "global" scope
|
||||
if(val == 0)
|
||||
throw Arabica::XPath::UnboundVariableException(clarkName);
|
||||
throw Arabica::XPath::UnboundVariableException(string_adaptor::asStdString(clarkName));
|
||||
|
||||
return val;
|
||||
} // resolveVariable
|
||||
|
|
Loading…
Reference in a new issue