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

View file

@ -139,7 +139,7 @@ const ChildElement* AllowedChildren()
static const ChildElement allowedChildren[] =
{
{ "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> > > },
{ "call-template", CreateHandler<CallTemplateHandler<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
{
template<class string_type, class string_adaptor>
class ApplyTemplates : public Item,
public Sortable,
public WithParamable
{
public:
ApplyTemplates(Arabica::XPath::XPathExpressionPtr<std::string> select,
std::string& mode) :
ApplyTemplates(Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> select,
string_type& mode) :
select_(select),
mode_(mode)
{
} // 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);
@ -33,13 +35,13 @@ public:
return;
}
Arabica::XPath::NodeSet<std::string> nodes;
Arabica::XPath::NodeSet<string_type, string_adaptor> nodes;
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);
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)
throw std::runtime_error("apply-templates select expression is not a node-set");
nodes = value.asNodeSet();
@ -49,8 +51,8 @@ public:
} // execute
private:
Arabica::XPath::XPathExpressionPtr<std::string> select_;
std::string mode_;
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> select_;
string_type mode_;
}; // class ApplyTemplates
} // namespace XSLT