more templating

This commit is contained in:
Jez Higgins 2012-11-09 19:17:13 +00:00
parent a78bb814f8
commit 03cf2ed1a9
23 changed files with 101 additions and 82 deletions

View file

@ -51,7 +51,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:apply-imports");
verifyNoCharacterData<string_type>(ch, "xsl:apply-imports");
} // characters
private:

View file

@ -48,7 +48,7 @@ public:
return;
} // if(applyTemplates_ == 0)
if(namespaceURI == StylesheetConstant::NamespaceURI())
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
{
if(localName == "sort")
{
@ -87,7 +87,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:apply-templates");
verifyNoCharacterData<string_type>(ch, "xsl:apply-templates");
} // characters
private:

View file

@ -40,7 +40,7 @@ public:
return;
} // if(callTemplate_ == 0)
if((namespaceURI == StylesheetConstant::NamespaceURI()) && (localName == "with-param"))
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) && (localName == "with-param"))
{
context_.push(0,
new WithParamHandler<string_type, string_adaptor>(context_, *callTemplate_),

View file

@ -112,7 +112,7 @@ public:
return;
} // if ...
if(namespaceURI == StylesheetConstant::NamespaceURI())
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
{
if(localName == "when")
{
@ -158,7 +158,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:choose");
verifyNoCharacterData<string_type>(ch, "xsl:choose");
} // characters
private:

View file

@ -6,17 +6,18 @@ namespace Arabica
namespace XSLT
{
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
struct StylesheetConstant
{
static const std::string& NamespaceURI()
static const string_type& NamespaceURI()
{
static std::string namespaceURI = "http://www.w3.org/1999/XSL/Transform";
static string_type namespaceURI = "http://www.w3.org/1999/XSL/Transform";
return namespaceURI;
} // XSLTNamespaceURI
static const std::string& Version()
static const string_type& Version()
{
static std::string version = "1.0";
static string_type version = "1.0";
return version;
} // Version
}; // struct StylesheetConstant

View file

@ -69,7 +69,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:copy-of");
verifyNoCharacterData<string_type>(ch, "xsl:copy-of");
} // characters
private:

View file

@ -40,7 +40,7 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
if((namespaceURI == StylesheetConstant::NamespaceURI()) &&
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) &&
(localName == "sort"))
{
if(!done_sort_)

View file

@ -6,33 +6,34 @@ namespace Arabica
namespace XSLT
{
class ForeignElementHandler : public SAX::DefaultHandler<std::string>
template<class string_type, class string_adaptor>
class ForeignElementHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{
public:
ForeignElementHandler(CompilationContext<std::string>& context) :
ForeignElementHandler(CompilationContext<string_type, string_adaptor>& context) :
context_(context),
depth_(0)
{
} // ForeignElementHandler
virtual void startElement(const std::string& /* namespaceURI */,
const std::string& /* localName */,
const std::string& /* qName */,
const SAX::Attributes<std::string>& /* atts */)
virtual void startElement(const string_type& /* namespaceURI */,
const string_type& /* localName */,
const string_type& /* qName */,
const SAX::Attributes<string_type, string_adaptor>& /* atts */)
{
++depth_;
} // startElement
virtual void endElement(const std::string& /* namespaceURI */,
const std::string& /* localName */,
const std::string& /* qName */)
virtual void endElement(const string_type& /* namespaceURI */,
const string_type& /* localName */,
const string_type& /* qName */)
{
if(--depth_ == 0)
context_.pop();
} // endElement
private:
CompilationContext<std::string>& context_;
CompilationContext<string_type, string_adaptor>& context_;
unsigned int depth_;
}; // class ForeignElementHandler

View file

@ -25,7 +25,7 @@ public:
{
static const ValueRule rules[] = { { "test", true, 0, 0 },
{ 0, false, 0, 0 } };
std::string test = gatherAttributes(qName, atts, rules)["test"];
string_type test = gatherAttributes(qName, atts, rules)["test"];
return new If<string_type, string_adaptor>(ItemContainerHandler<If<string_type, string_adaptor> >::context().xpath_expression(test));
} // startElement

View file

@ -50,7 +50,7 @@ public:
if(no_content_)
throw SAX::SAXException("xsl:include must be empty");
if(namespaceURI == StylesheetConstant::NamespaceURI())
if(namespaceURI == StylesheetConstant<std::string>::NamespaceURI())
{
if(localName == "import")
{
@ -82,7 +82,7 @@ public:
const std::string& qName)
{
if(no_content_ &&
(namespaceURI == StylesheetConstant::NamespaceURI()))
(namespaceURI == StylesheetConstant<std::string>::NamespaceURI()))
{
no_content_ = false;
if(localName == "include")
@ -103,7 +103,7 @@ public:
virtual void characters(const std::string& ch)
{
if(no_content_)
verifyNoCharacterData(ch, "xsl:include/xsl:import");
verifyNoCharacterData<std::string>(ch, "xsl:include/xsl:import");
context_->parentHandler().characters(ch);
} // characters

View file

@ -31,7 +31,7 @@ protected:
{
if(atts.getQName(i).find("xmlns:") == 0)
continue;
if(atts.getURI(i) == StylesheetConstant::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),

View file

@ -85,7 +85,7 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
if(namespaceURI == StylesheetConstant::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)
if(c->name == localName)

View file

@ -58,7 +58,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:key");
verifyNoCharacterData<string_type>(ch, "xsl:key");
} // characters
private:

View file

@ -62,7 +62,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:namespace-alias");
verifyNoCharacterData<string_type>(ch, "xsl:namespace-alias");
} // characters
private:

View file

@ -53,7 +53,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:output");
verifyNoCharacterData<string_type>(ch, "xsl:output");
} // characters
private:

View file

@ -66,7 +66,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:sort");
verifyNoCharacterData<string_type>(ch, "xsl:sort");
} // characters
private:

View file

@ -20,7 +20,7 @@ public:
{
} // TemplateHandler
virtual void characters(const std::string& ch)
virtual void characters(const string_type& ch)
{
if(!done_params_)
{
@ -92,7 +92,7 @@ protected:
const string_type& qName,
const SAX::Attributes<string_type, string_adaptor>& atts)
{
if((namespaceURI == StylesheetConstant::NamespaceURI()) &&
if((namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) &&
(localName == "param"))
{
if(!done_params_)

View file

@ -49,7 +49,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:value-of");
verifyNoCharacterData<string_type>(ch, "xsl:value-of");
} // characters
private:

View file

@ -19,8 +19,11 @@ static const char* Yes = "yes";
static const char* AllowedYesNo[] = { No, Yes, 0 };
static const char* DefaultPreserve[] = { "default", "preserve", 0 };
void validateValues(const std::string& parentElement, const std::string& name,
const std::string& value, const char** allowed)
template<class string_type>
void validateValues(const string_type& parentElement,
const string_type& name,
const string_type& value,
const char** allowed)
{
for(const char* const* a = allowed; *a != 0; ++a)
if(value == *a)
@ -33,9 +36,11 @@ void validateValues(const std::string& parentElement, const std::string& name,
throw SAX::SAXException(os.str());
} // validateValues
void validateXmlAttribute(const std::string& parentElement,
const std::string& name, const std::string& value,
std::map<std::string, std::string>& results)
template<class string_type>
void validateXmlAttribute(const string_type& parentElement,
const string_type& name,
const string_type& value,
std::map<string_type, string_type>& results)
{
results[name] = value;
@ -43,10 +48,12 @@ void validateXmlAttribute(const std::string& parentElement,
validateValues(parentElement, name, value, DefaultPreserve);
} // validateXmlAttribute
void validateAttribute(const std::string& parentElement,
const std::string& name, const std::string& value,
template<class string_type>
void validateAttribute(const string_type& parentElement,
const string_type& name,
const string_type& value,
const ValueRule* rules,
std::map<std::string, std::string>& results)
std::map<string_type, string_type>& results)
{
while((rules->name != 0) && (name != rules->name))
++rules;
@ -60,11 +67,12 @@ void validateAttribute(const std::string& parentElement,
validateValues(parentElement, name, value, rules->allowed);
} // validateAttribute
std::map<std::string, std::string> gatherAttributes(const std::string& parentElement,
const SAX::Attributes<std::string>& atts,
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)
{
std::map<std::string, std::string> results;
std::map<string_type, string_type> results;
for(const ValueRule* r = rules ; r->name != 0; ++r)
{
@ -90,10 +98,11 @@ std::map<std::string, std::string> gatherAttributes(const std::string& parentEle
return results;
} // validateAttributes
void verifyNoCharacterData(const std::string& ch,
const std::string& name)
template<class string_type>
void verifyNoCharacterData(const string_type& ch,
const string_type& name)
{
for(std::string::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i)
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.");
} // verifyNoCharacterContent

View file

@ -14,50 +14,54 @@ template<class VType>
class VariableHandler : public ItemContainerHandler<VType>
{
public:
VariableHandler(CompilationContext<std::string>& context) :
ItemContainerHandler<VType>(context),
typedef typename VType::string_type string_type;
typedef typename VType::string_adaptor string_adaptor;
typedef ItemContainerHandler<VType> baseT;
VariableHandler(CompilationContext<string_type, string_adaptor>& context) :
baseT(context),
has_select_(false),
precedence_(Precedence::FrozenPrecedence())
{
} // VariableHandler
VariableHandler(CompilationContext<std::string>& context, const Precedence& precedence) :
ItemContainerHandler<VType>(context),
VariableHandler(CompilationContext<string_type, string_adaptor>& context, const Precedence& precedence) :
baseT(context),
has_select_(false),
precedence_(precedence)
{
} // VariableHandler
protected:
virtual VType* createContainer(const std::string& /* namespaceURI */,
const std::string& /* localName */,
const std::string& qName,
const SAX::Attributes<std::string>& atts)
virtual VType* createContainer(const string_type& /* namespaceURI */,
const string_type& /* localName */,
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 } };
std::map<std::string, std::string> attrs = gatherAttributes(qName, atts, rules);
std::map<string_type, string_type> attrs = gatherAttributes(qName, atts, rules);
const std::string& select = atts.getValue("select");
Arabica::XPath::XPathExpressionPtr<std::string> xpath;
const string_type& select = atts.getValue("select");
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> xpath;
if(select != "")
{
xpath = this->context().xpath_expression(select);
xpath = baseT::context().xpath_expression(select);
has_select_ = true;
} // if ...
std::string name = this->context().processInternalQName(attrs["name"]).clarkName();
string_type name = baseT::context().processInternalQName(attrs["name"]).clarkName();
return new VType(name, xpath, precedence_);
} // createContainer
virtual void characters(const std::string& ch)
virtual void characters(const string_type& ch)
{
if(has_select_)
{
for(std::string::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i)
for(string_type::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i)
if(!Arabica::XML::is_space(*i))
throw SAX::SAXException("A variable or param can not have both a select attribute and text context");
}
@ -73,17 +77,21 @@ template<class VType>
class TopLevelVariableHandler : public VariableHandler<VType>
{
public:
TopLevelVariableHandler(CompilationContext<std::string>& context) :
VariableHandler<VType>(context, context.precedence())
typedef typename VType::string_type string_type;
typedef typename VType::string_adaptor string_adaptor;
typedef VariableHandler<VType> baseT;
TopLevelVariableHandler(CompilationContext<string_type, string_adaptor>& context) :
baseT(context, context.precedence())
{
} // VariableHandler
virtual void endElement(const std::string& /* namespaceURI */,
const std::string& /* localName */,
const std::string& /* qName */)
virtual void endElement(const string_type& /* namespaceURI */,
const string_type& /* localName */,
const string_type& /* qName */)
{
this->context().stylesheet().add_variable(this->container());
this->context().pop();
baseT::context().stylesheet().add_variable(baseT::container());
baseT::context().pop();
} // endElement
}; // class TopLevelVariableHandler

View file

@ -269,7 +269,7 @@ protected:
const string_type functionName = baseT::argAsString(0, context, executionContext);
const QualifiedName expandedName = QualifiedName::parseQName(functionName, true, namespaces_);
if((expandedName.namespaceUri() != StylesheetConstant::NamespaceURI()) &&
if((expandedName.namespaceUri() != StylesheetConstant<string_type, string_adaptor>::NamespaceURI()) &&
(!expandedName.namespaceUri().empty()))
return false;

View file

@ -44,9 +44,9 @@ public:
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("xsl:sort", "data-type", datatype, allowed_datatypes);
validateValues("xsl:sort", "order", order, allowed_orders);
validateValues("xsl:sort", "case-order", caseorder, allowed_case_orders);
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);
if(datatype == "number")
if(order == "ascending")

View file

@ -52,14 +52,14 @@ public:
if(top_)
{
top_ = false;
if(namespaceURI == StylesheetConstant::NamespaceURI())
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
startStylesheet(namespaceURI, localName, qName, atts);
else
startLREAsStylesheet(namespaceURI, localName, qName, atts);
return;
} // if(top_)
if(namespaceURI == StylesheetConstant::NamespaceURI())
if(namespaceURI == StylesheetConstant<string_type, string_adaptor>::NamespaceURI())
startXSLTElement(namespaceURI, localName, qName, atts);
else if(!namespaceURI.empty())
startForeignElement(namespaceURI, localName, qName, atts);
@ -75,7 +75,7 @@ public:
virtual void characters(const string_type& ch)
{
verifyNoCharacterData(ch, "xsl:stylesheet/xsl:transform");
verifyNoCharacterData<string_type>(ch, "xsl:stylesheet/xsl:transform");
} // characters
virtual void endDocument()
@ -99,7 +99,7 @@ private:
{ "id", false, 0, 0 },
{ 0, false, 0, 0 } };
std::map<string_type, string_type> attributes = gatherAttributes(qName, atts, rules);
if(attributes["version"] != StylesheetConstant::Version())
if(attributes["version"] != StylesheetConstant<string_type, string_adaptor>::Version())
throw SAX::SAXException("I'm only a poor version 1.0 XSLT Transformer.");
if(!attributes["extension-element-prefixes"].empty())
throw SAX::SAXException("Haven't implemented extension-element-prefixes yet");
@ -112,7 +112,7 @@ private:
{
string_type version;
for(int a = 0; a != atts.getLength(); ++a)
if((StylesheetConstant::NamespaceURI() == atts.getURI(a)) &&
if((StylesheetConstant<string_type, string_adaptor>::NamespaceURI() == atts.getURI(a)) &&
("version" == atts.getLocalName(a)))
{
version = atts.getValue(a);
@ -121,7 +121,7 @@ private:
if(version.empty())
throw SAX::SAXException("The source file does not look like a stylesheet.");
if(version != StylesheetConstant::Version())
if(version != StylesheetConstant<string_type, string_adaptor>::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());
@ -165,7 +165,7 @@ private:
const AttributesT& atts)
{
context_.push(0,
new ForeignElementHandler(context_),
new ForeignElementHandler<string_type, string_adaptor>(context_),
namespaceURI,
localName,
qName,