arabica/include/XSLT/impl/xslt_copy.hpp

148 lines
4.5 KiB
C++
Raw Normal View History

2007-07-19 19:01:42 +02:00
#ifndef ARABICA_XSLT_COPY_HPP
#define ARABICA_XSLT_COPY_HPP
#include "xslt_item.hpp"
namespace Arabica
{
namespace XSLT
{
2012-11-04 18:12:14 +01:00
template<class string_type, class string_adaptor>
2007-07-19 19:01:42 +02:00
class Copy_base : public ItemContainer
{
protected:
Copy_base()
{
2012-11-04 18:12:14 +01:00
Arabica::XPath::XPath<string_type, string_adaptor> compiler;
2007-07-19 19:01:42 +02:00
namespace_select_ = compiler.compile("namespace::node()");
} // Copy_base
virtual ~Copy_base() { }
protected:
2012-11-04 18:12:14 +01:00
void copy(const DOM::Node<string_type, string_adaptor>& node, ExecutionContext& context) const
2007-07-19 19:01:42 +02:00
{
switch(node.getNodeType())
{
case DOM::Node_base::ATTRIBUTE_NODE:
context.sink().add_attribute(node.getNamespaceURI(),
node.getLocalName(),
node.getNodeName(),
node.getNodeValue());
break;
case DOM::Node_base::COMMENT_NODE:
context.sink().start_comment();
context.sink().characters(node.getNodeValue());
context.sink().end_comment();
break;
case DOM::Node_base::DOCUMENT_NODE:
case DOM::Node_base::DOCUMENT_FRAGMENT_NODE:
process_content(node, context);
break;
case DOM::Node_base::ELEMENT_NODE:
if(context.sink().start_element(node.getPrefix(), node.getLocalName(), node.getNamespaceURI()))
{
process_content(node, context);
context.sink().end_element(node.getPrefix(), node.getLocalName(), node.getNamespaceURI());
}
break;
case DOM::Node_base::PROCESSING_INSTRUCTION_NODE:
context.sink().start_processing_instruction(node.getNodeName());
context.sink().characters(node.getNodeValue());
context.sink().end_processing_instruction();
break;
case DOM::Node_base::TEXT_NODE:
case DOM::Node_base::CDATA_SECTION_NODE:
context.sink().characters(node.getNodeValue());
break;
} // switch
} // execute
2012-11-04 18:12:14 +01:00
virtual void process_content(const DOM::Node<string_type, string_adaptor>& node, ExecutionContext& context) const = 0;
2007-07-19 19:01:42 +02:00
private:
2012-11-04 18:12:14 +01:00
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> namespace_select_;
2007-07-19 19:01:42 +02:00
}; // class Copy_base
2012-11-04 23:34:40 +01:00
template<class stringT, class adaptorT>
class Copy : public Copy_base<stringT, adaptorT>
2007-07-19 19:01:42 +02:00
{
public:
2012-11-04 23:34:40 +01:00
typedef stringT string_type;
typedef adaptorT string_adaptor;
2012-11-04 18:12:14 +01:00
Copy(const string_type& attributes_sets) :
2007-07-19 19:01:42 +02:00
attributes_sets_(attributes_sets)
{
} // Copy
virtual ~Copy() { }
2012-11-04 18:12:14 +01:00
virtual void execute(const DOM::Node<string_type, string_adaptor>& node, ExecutionContext& context) const
2007-07-19 19:01:42 +02:00
{
copy(node, context);
} // execute
protected:
2012-11-04 18:12:14 +01:00
virtual void process_content(const DOM::Node<string_type, string_adaptor>& node, ExecutionContext& context) const
2007-07-19 19:01:42 +02:00
{
execute_children(node, context);
} // process_content
private:
2012-11-04 18:12:14 +01:00
string_type attributes_sets_;
2007-07-19 19:01:42 +02:00
}; // class Copy
2012-11-04 23:34:40 +01:00
template<class stringT, class adaptorT>
class CopyOf : public Copy_base<stringT, adaptorT>
2007-07-19 19:01:42 +02:00
{
public:
2012-11-04 23:34:40 +01:00
typedef stringT string_type;
typedef adaptorT string_adaptor;
2012-11-04 18:12:14 +01:00
CopyOf(const Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor>& select) :
2007-07-19 19:01:42 +02:00
select_(select)
{
} // CopyOf
virtual ~CopyOf() { }
2012-11-04 18:12:14 +01:00
virtual void execute(const DOM::Node<string_type, string_adaptor>& node, ExecutionContext& context) const
2007-07-19 19:01:42 +02:00
{
2012-11-04 18:12:14 +01:00
Arabica::XPath::XPathValue<string_type, string_adaptor> value = select_->evaluate(node, context.xpathContext());
2009-02-18 09:37:16 +01:00
if(value.type() != Arabica::XPath::NODE_SET)
2007-07-19 19:01:42 +02:00
{
2009-02-18 09:37:16 +01:00
context.sink().characters(value.asString());
2007-07-19 19:01:42 +02:00
return;
}
2012-11-04 18:12:14 +01:00
Arabica::XPath::NodeSet<string_type, string_adaptor> nodes = value.asNodeSet();
2012-11-04 18:15:34 +01:00
for(typename Arabica::XPath::NodeSet<string_type, string_adaptor>::const_iterator n = nodes.begin(), e = nodes.end(); n != e; ++n)
2007-07-19 19:01:42 +02:00
copy(*n, context);
} // execute
protected:
2012-11-04 18:12:14 +01:00
virtual void process_content(const DOM::Node<string_type, string_adaptor>& node, ExecutionContext& context) const
2007-07-19 19:01:42 +02:00
{
if(node.hasAttributes())
{
2012-11-04 18:12:14 +01:00
const DOM::NamedNodeMap<string_type, string_adaptor>& attrs = node.getAttributes();
2007-07-19 19:01:42 +02:00
for(unsigned int a = 0; a < attrs.getLength(); ++a)
copy(attrs.item(a), context);
} // if ...
2012-11-04 18:12:14 +01:00
for(DOM::Node<string_type, string_adaptor> n = node.getFirstChild(); n != 0; n = n.getNextSibling())
2007-07-19 19:01:42 +02:00
copy(n, context);
} // process_content
private:
2012-11-04 18:12:14 +01:00
Arabica::XPath::XPathExpressionPtr<string_type, string_adaptor> select_;
2007-07-19 19:01:42 +02:00
}; // class CopyOf
} // namespace XSLT
} // namespace Arabica
#endif