arabica/include/XSLT/impl/xslt_namespace_stack.hpp

97 lines
2.5 KiB
C++
Raw Normal View History

2007-07-19 19:01:42 +02:00
#ifndef ARABICA_XSLT_NAMESPACE_STACK_HPP
#define ARABICA_XSLT_NAMESPACE_STACK_HPP
#include <map>
#include <vector>
#include "handler/xslt_constants.hpp"
2007-07-19 19:01:42 +02:00
namespace Arabica
{
namespace XSLT
{
template<class string_type, class string_adaptor>
2007-07-19 19:01:42 +02:00
class NamespaceStack
{
typedef StylesheetConstant<string_type, string_adaptor> SC;
2007-07-19 19:01:42 +02:00
public:
2012-11-09 20:24:27 +01:00
typedef std::map<string_type, string_type> Scope;
2007-07-19 19:01:42 +02:00
NamespaceStack() :
autoNs_(1)
{
prefixStack_.push_back(Scope());
uriStack_.push_back(Scope());
} // NamespaceStack
void pushScope()
{
prefixStack_.push_back(Scope());
uriStack_.push_back(Scope());
} // pushScope
void popScope()
{
prefixStack_.pop_back();
uriStack_.pop_back();
} // popScope
2012-11-09 20:24:27 +01:00
void declareNamespace(const string_type& given_prefix, const string_type& namespaceURI, bool attr = false)
2007-07-19 19:01:42 +02:00
{
if(findPrefix(namespaceURI) != EMPTY_STRING)
return;
2012-11-21 07:59:40 +01:00
bool remap = (attr && string_adaptor::empty(given_prefix)) || (given_prefix == SC::xmlns);
2007-07-19 19:01:42 +02:00
2012-11-09 20:24:27 +01:00
string_type prefix = !remap ? given_prefix : autoNamespacePrefix();
2007-07-19 19:01:42 +02:00
prefixStack_.back()[prefix] = namespaceURI;
uriStack_.back()[namespaceURI] = prefix;
} // declareNamespace
2012-11-09 20:24:27 +01:00
const string_type& findURI(const string_type& prefix) const
2007-07-19 19:01:42 +02:00
{
return searchStack(prefixStack_, prefix);
} // findURI
2012-11-09 20:24:27 +01:00
const string_type& findPrefix(const string_type& uri) const
2007-07-19 19:01:42 +02:00
{
return searchStack(uriStack_, uri);
} // findPrefix
2012-11-09 20:24:27 +01:00
typename Scope::const_iterator begin() { return prefixStack_.back().begin(); }
typename Scope::const_iterator end() { return prefixStack_.back().end(); }
2007-07-19 19:01:42 +02:00
private:
typedef std::vector<Scope> ScopeStack;
2012-11-09 20:24:27 +01:00
const string_type& searchStack(const ScopeStack& stack, const string_type& key) const
2007-07-19 19:01:42 +02:00
{
2012-11-15 23:06:46 +01:00
for(typename ScopeStack::const_reverse_iterator ss = stack.rbegin(), se = stack.rend(); ss != se; ss++)
2007-07-19 19:01:42 +02:00
{
2012-11-15 23:06:46 +01:00
typename Scope::const_iterator i = ss->find(key);
2007-07-19 19:01:42 +02:00
if(i != ss->end())
return i->second;
}
return EMPTY_STRING;
} // searchStack
2012-11-09 20:24:27 +01:00
string_type autoNamespacePrefix()
2007-07-19 19:01:42 +02:00
{
std::basic_ostringstream<typename string_adaptor::value_type> ss;
ss << SC::auto_ns << autoNs_++;
2012-11-21 07:59:40 +01:00
return string_adaptor::construct(ss.str());
2007-07-19 19:01:42 +02:00
} // autoNamespacePrefix
ScopeStack prefixStack_;
ScopeStack uriStack_;
2012-11-09 20:24:27 +01:00
string_type EMPTY_STRING;
2007-07-19 19:01:42 +02:00
unsigned int autoNs_;
}; // class NamespaceStack
} // namespace XSLT
} // namespace Arabica
#endif // ARABICA_XSLT_NAMESPACE_STACK_HPP