First pass as parameterising the whole of the XSLT library on string_type is done

This commit is contained in:
Jez Higgins 2012-11-12 21:46:08 +00:00
parent 16b50bf4df
commit 39d85b29c6
47 changed files with 871 additions and 514 deletions

View file

@ -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();

View file

@ -1,101 +1,101 @@
#ifndef ARABICA_SAX_NAMESPACE_TRACKER_HPP
#define ARABICA_SAX_NAMESPACE_TRACKER_HPP
#include <map>
#include <SAX/ArabicaConfig.hpp>
#include <SAX/helpers/XMLFilterImpl.hpp>
#include <SAX/helpers/NamespaceSupport.hpp>
#include <Arabica/StringAdaptor.hpp>
namespace Arabica
{
namespace SAX
{
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class NamespaceTracker : public XMLFilterImpl<string_type, string_adaptor>
{
typedef XMLFilterImpl<string_type, string_adaptor> XMLFilterT;
typedef NamespaceSupport<string_type, string_adaptor> NamespaceSupportT;
typedef typename NamespaceSupportT::stringListT stringListT;
public:
typedef XMLReaderInterface<string_type, string_adaptor> XMLReaderT;
typedef Attributes<string_type, string_adaptor> AttributesT;
NamespaceTracker() :
XMLFilterT()
{
} // NamespaceTracker
NamespaceTracker(XMLReaderT& parent) :
XMLFilterT(parent)
{
} // NamespaceTracker
virtual ~NamespaceTracker() { }
XML::QualifiedName<string_type, string_adaptor> processElementName(const string_type& rawName) const
{
return namespaces_.processName(rawName, false);
} // process
XML::QualifiedName<string_type, string_adaptor> processName(const string_type& rawName) const
{
return namespaces_.processName(rawName, true);
} // process
string_type getURI(const string_type& prefix) const
{
return namespaces_.getURI(prefix);
} // getURI
std::map<string_type, string_type> inScopeNamespaces() const
{
std::map<string_type, string_type> ns;
stringListT prefixes = namespaces_.getPrefixes();
for(typename stringListT::const_iterator p = prefixes.begin(), pe = prefixes.end(); p != pe; ++p)
{
if(ns.find(*p) != ns.end())
continue;
ns[*p] = namespaces_.getURI(*p);
} // for ...
ns[""] = namespaces_.getURI("");
return ns;
} // inScopeNamespaces
virtual void startElement(const string_type& namespaceURI, const string_type& localName,
const string_type& qName, const AttributesT& atts)
{
namespaces_.pushContext();
for(typename std::map<string_type, string_type>::const_iterator i = buffer_.begin(), ie = buffer_.end(); i != ie; ++i)
namespaces_.declarePrefix(i->first, i->second);
buffer_.clear();
XMLFilterT::startElement(namespaceURI, localName, qName, atts);
} // startElement
virtual void endElement(const string_type& namespaceURI, const string_type& localName,
const string_type& qName)
{
XMLFilterT::endElement(namespaceURI, localName, qName);
namespaces_.popContext();
} // endElement
virtual void startPrefixMapping(const string_type& prefix, const string_type& uri)
{
// startPrefixMappings precede the startElement, so buffer 'em up
buffer_[prefix] = uri;
XMLFilterT::startPrefixMapping(prefix, uri);
} // startPrefixMapping
private:
NamespaceSupportT namespaces_;
std::map<string_type, string_type> buffer_;
}; // class NamespaceTracker
} // namespace SAX
} // namespace Arabica
#endif
#ifndef ARABICA_SAX_NAMESPACE_TRACKER_HPP
#define ARABICA_SAX_NAMESPACE_TRACKER_HPP
#include <map>
#include <SAX/ArabicaConfig.hpp>
#include <SAX/helpers/XMLFilterImpl.hpp>
#include <SAX/helpers/NamespaceSupport.hpp>
#include <Arabica/StringAdaptor.hpp>
namespace Arabica
{
namespace SAX
{
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class NamespaceTracker : public XMLFilterImpl<string_type, string_adaptor>
{
typedef XMLFilterImpl<string_type, string_adaptor> XMLFilterT;
typedef NamespaceSupport<string_type, string_adaptor> NamespaceSupportT;
typedef typename NamespaceSupportT::stringListT stringListT;
public:
typedef XMLReaderInterface<string_type, string_adaptor> XMLReaderT;
typedef Attributes<string_type, string_adaptor> AttributesT;
NamespaceTracker() :
XMLFilterT()
{
} // NamespaceTracker
NamespaceTracker(XMLReaderT& parent) :
XMLFilterT(parent)
{
} // NamespaceTracker
virtual ~NamespaceTracker() { }
XML::QualifiedName<string_type, string_adaptor> processElementName(const string_type& rawName) const
{
return namespaces_.processName(rawName, false);
} // process
XML::QualifiedName<string_type, string_adaptor> processName(const string_type& rawName) const
{
return namespaces_.processName(rawName, true);
} // process
string_type getURI(const string_type& prefix) const
{
return namespaces_.getURI(prefix);
} // getURI
std::map<string_type, string_type> inScopeNamespaces() const
{
std::map<string_type, string_type> ns;
stringListT prefixes = namespaces_.getPrefixes();
for(typename stringListT::const_iterator p = prefixes.begin(), pe = prefixes.end(); p != pe; ++p)
{
if(ns.find(*p) != ns.end())
continue;
ns[*p] = namespaces_.getURI(*p);
} // for ...
ns[string_adaptor::empty_string()] = namespaces_.getURI(string_adaptor::empty_string());
return ns;
} // inScopeNamespaces
virtual void startElement(const string_type& namespaceURI, const string_type& localName,
const string_type& qName, const AttributesT& atts)
{
namespaces_.pushContext();
for(typename std::map<string_type, string_type>::const_iterator i = buffer_.begin(), ie = buffer_.end(); i != ie; ++i)
namespaces_.declarePrefix(i->first, i->second);
buffer_.clear();
XMLFilterT::startElement(namespaceURI, localName, qName, atts);
} // startElement
virtual void endElement(const string_type& namespaceURI, const string_type& localName,
const string_type& qName)
{
XMLFilterT::endElement(namespaceURI, localName, qName);
namespaces_.popContext();
} // endElement
virtual void startPrefixMapping(const string_type& prefix, const string_type& uri)
{
// startPrefixMappings precede the startElement, so buffer 'em up
buffer_[prefix] = uri;
XMLFilterT::startPrefixMapping(prefix, uri);
} // startPrefixMapping
private:
NamespaceSupportT namespaces_;
std::map<string_type, string_type> buffer_;
}; // class NamespaceTracker
} // namespace SAX
} // namespace Arabica
#endif

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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_),

View file

@ -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:

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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_)
{

View file

@ -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

View file

@ -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 },
{ 0, false, 0, 0 } };
string_type href = gatherAttributes(qName, atts, rules)["href"];
static const ValueRule<string_type> rules[] = { { SC::href, true, 0, 0 },
{ 0, false, 0, 0 } };
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

View file

@ -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

View file

@ -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

View file

@ -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
@ -49,8 +50,8 @@ public:
} // startElement
virtual void endElement(const string_type& /* namespaceURI */,
const string_type& /* localName */,
const string_type& /* qName */)
const string_type& /* localName */,
const string_type& /* qName */)
{
context_.stylesheet().add_key(name_, key_);
context_.pop();
@ -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:

View file

@ -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

View file

@ -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:

View file

@ -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;

View file

@ -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

View file

@ -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 },
{ 0, false, 0, 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:

View file

@ -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_)
{

View file

@ -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 */,

View file

@ -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 },
{ 0, false, 0, 0 } };
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:

View file

@ -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

View file

@ -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

View file

@ -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 ...

View file

@ -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

View file

@ -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

View file

@ -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() { }

View file

@ -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 ...

View file

@ -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),

View file

@ -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_;

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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,17 +146,17 @@ 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;
} // do_start_element
void do_end_element(const string_type& qName,
const string_type& /* namespaceURI */)
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;

View file

@ -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;

View file

@ -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

View file

@ -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 },
{ 0, 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

View file

@ -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_;

View file

@ -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())

View file

@ -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

View file

@ -21,7 +21,7 @@ namespace Arabica
host_(rhs.host_),
path_(rhs.path_),
port_(rhs.port_),
is_absolute_(rhs.is_absolute_)
is_absolute_(rhs.is_absolute_)
{
} // URI
@ -54,7 +54,7 @@ namespace Arabica
std::swap(host_, rhs.host_);
std::swap(path_, rhs.path_);
std::swap(port_, rhs.port_);
std::swap(is_absolute_, rhs.is_absolute_);
std::swap(is_absolute_, rhs.is_absolute_);
} // swap
const std::string& scheme() const { return scheme_; }