apply_templates

This commit is contained in:
Jez Higgins 2012-11-03 09:54:07 +00:00
parent 21fb29d396
commit 4ddf44c269
3 changed files with 29 additions and 26 deletions

View file

@ -10,36 +10,37 @@ namespace Arabica
namespace XSLT namespace XSLT
{ {
class ApplyTemplatesHandler : public SAX::DefaultHandler<std::string> template<class string_type, class string_adaptor>
class ApplyTemplatesHandler : public SAX::DefaultHandler<string_type, string_adaptor>
{ {
public: public:
ApplyTemplatesHandler(CompilationContext<std::string>& context) : ApplyTemplatesHandler(CompilationContext<string_type, string_adaptor>& context) :
context_(context), context_(context),
applyTemplates_(0) applyTemplates_(0)
{ {
} // ApplyTemplatesHandler } // ApplyTemplatesHandler
virtual void startElement(const std::string& namespaceURI, virtual void startElement(const string_type& namespaceURI,
const std::string& localName, const string_type& localName,
const std::string& qName, const string_type& qName,
const SAX::Attributes<std::string>& atts) const SAX::Attributes<string_type, string_adaptor>& atts)
{ {
if(applyTemplates_ == 0) if(applyTemplates_ == 0)
{ {
static const ValueRule rules[] = { { "select", false, 0, 0 }, static const ValueRule rules[] = { { "select", false, 0, 0 },
{ "mode", false, 0, 0 }, { "mode", false, 0, 0 },
{ 0, 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 = attrs["select"]; const string_type& select = attrs["select"];
Arabica::XPath::XPathExpressionPtr<std::string> xpath; Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> xpath;
if(select != "") if(select != "")
xpath = context_.xpath_expression(select); xpath = context_.xpath_expression(select);
std::string mode; string_type mode;
if(attrs["mode"] != "") if(attrs["mode"] != "")
mode = context_.processInternalQName(attrs["mode"]).clarkName(); mode = context_.processInternalQName(attrs["mode"]).clarkName();
applyTemplates_ = new ApplyTemplates(xpath, mode); applyTemplates_ = new ApplyTemplates<string_type, string_adaptor>(xpath, mode);
return; return;
} // if(applyTemplates_ == 0) } // if(applyTemplates_ == 0)
@ -73,22 +74,22 @@ public:
throw SAX::SAXException("xsl:apply-templates can only contain xsl:sort and xsl:with-param elements."); throw SAX::SAXException("xsl:apply-templates can only contain xsl:sort and xsl:with-param elements.");
} // startElement } // startElement
virtual void endElement(const std::string& /* namespaceURI */, virtual void endElement(const string_type& /* namespaceURI */,
const std::string& /* localName */, const string_type& /* localName */,
const std::string& /* qName */) const string_type& /* qName */)
{ {
context_.parentContainer().add_item(applyTemplates_); context_.parentContainer().add_item(applyTemplates_);
context_.pop(); context_.pop();
} // endElement } // endElement
virtual void characters(const std::string& ch) virtual void characters(const string_type& ch)
{ {
verifyNoCharacterData(ch, "xsl:apply-templates"); verifyNoCharacterData(ch, "xsl:apply-templates");
} // characters } // characters
private: private:
CompilationContext<std::string>& context_; CompilationContext<string_type, string_adaptor>& context_;
ApplyTemplates* applyTemplates_; ApplyTemplates<string_type, string_adaptor>* applyTemplates_;
}; // class ApplyTemplatesHandler }; // class ApplyTemplatesHandler
} // namespace XSLT } // namespace XSLT

View file

@ -139,7 +139,7 @@ const ChildElement* AllowedChildren()
static const ChildElement allowedChildren[] = static const ChildElement allowedChildren[] =
{ {
{ "apply-imports", CreateHandler<ApplyImportsHandler<std::string, Arabica::default_string_adaptor<std::string> > > }, { "apply-imports", CreateHandler<ApplyImportsHandler<std::string, Arabica::default_string_adaptor<std::string> > > },
{ "apply-templates", CreateHandler<ApplyTemplatesHandler> }, { "apply-templates", CreateHandler<ApplyTemplatesHandler<std::string, Arabica::default_string_adaptor<std::string> > > },
{ "attribute", CreateHandler<AttributeHandler<std::string, Arabica::default_string_adaptor<std::string> > > }, { "attribute", CreateHandler<AttributeHandler<std::string, Arabica::default_string_adaptor<std::string> > > },
{ "call-template", CreateHandler<CallTemplateHandler<std::string, Arabica::default_string_adaptor<std::string> > > }, { "call-template", CreateHandler<CallTemplateHandler<std::string, Arabica::default_string_adaptor<std::string> > > },
{ "choose", CreateHandler<ChooseHandler<std::string, Arabica::default_string_adaptor<std::string> > > }, { "choose", CreateHandler<ChooseHandler<std::string, Arabica::default_string_adaptor<std::string> > > },

View file

@ -10,19 +10,21 @@ namespace Arabica
namespace XSLT namespace XSLT
{ {
template<class string_type, class string_adaptor>
class ApplyTemplates : public Item, class ApplyTemplates : public Item,
public Sortable, public Sortable,
public WithParamable public WithParamable
{ {
public: public:
ApplyTemplates(Arabica::XPath::XPathExpressionPtr<std::string> select, ApplyTemplates(Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> select,
std::string& mode) : string_type& mode) :
select_(select), select_(select),
mode_(mode) mode_(mode)
{ {
} // ApplyTemplates } // ApplyTemplates
virtual void execute(const DOM::Node<std::string>& node, ExecutionContext& context) const virtual void execute(const DOM::Node<string_type, string_adaptor>& node,
ExecutionContext& context) const
{ {
ParamPasser passer(*this, node, context); ParamPasser passer(*this, node, context);
@ -33,13 +35,13 @@ public:
return; return;
} }
Arabica::XPath::NodeSet<std::string> nodes; Arabica::XPath::NodeSet<string_type, string_adaptor> nodes;
if(select_ == 0) if(select_ == 0)
for(DOM::Node<std::string> n = node.getFirstChild(); n != 0; n = n.getNextSibling()) for(DOM::Node<string_type, string_adaptor> n = node.getFirstChild(); n != 0; n = n.getNextSibling())
nodes.push_back(n); nodes.push_back(n);
else else
{ {
Arabica::XPath::XPathValue<std::string> value = select_->evaluate(node, context.xpathContext()); Arabica::XPath::XPathValue<string_type, string_adaptor> value = select_->evaluate(node, context.xpathContext());
if(value.type() != Arabica::XPath::NODE_SET) if(value.type() != Arabica::XPath::NODE_SET)
throw std::runtime_error("apply-templates select expression is not a node-set"); throw std::runtime_error("apply-templates select expression is not a node-set");
nodes = value.asNodeSet(); nodes = value.asNodeSet();
@ -49,8 +51,8 @@ public:
} // execute } // execute
private: private:
Arabica::XPath::XPathExpressionPtr<std::string> select_; Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> select_;
std::string mode_; string_type mode_;
}; // class ApplyTemplates }; // class ApplyTemplates
} // namespace XSLT } // namespace XSLT