arabica/include/XSLT/impl/xslt_namespace_stack.hpp

93 lines
2.2 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>
namespace Arabica
{
namespace XSLT
{
class NamespaceStack
{
public:
typedef std::map<std::string, std::string> Scope;
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
void declareNamespace(const std::string& given_prefix, const std::string& namespaceURI, bool attr = false)
{
if(findPrefix(namespaceURI) != EMPTY_STRING)
return;
bool remap = (attr && given_prefix.empty()) || (given_prefix == "xmlns");
std::string prefix = !remap ? given_prefix : autoNamespacePrefix();
prefixStack_.back()[prefix] = namespaceURI;
uriStack_.back()[namespaceURI] = prefix;
} // declareNamespace
const std::string& findURI(const std::string& prefix) const
{
return searchStack(prefixStack_, prefix);
} // findURI
const std::string& findPrefix(const std::string& uri) const
{
return searchStack(uriStack_, uri);
} // findPrefix
Scope::const_iterator begin() { return prefixStack_.back().begin(); }
Scope::const_iterator end() { return prefixStack_.back().end(); }
private:
typedef std::vector<Scope> ScopeStack;
const std::string& searchStack(const ScopeStack& stack, const std::string& key) const
{
for(ScopeStack::const_reverse_iterator ss = stack.rbegin(), se = stack.rend(); ss != se; ss++)
{
Scope::const_iterator i = ss->find(key);
if(i != ss->end())
return i->second;
}
return EMPTY_STRING;
} // searchStack
std::string autoNamespacePrefix()
{
std::ostringstream ss;
ss << "auto-ns" << autoNs_++;
return ss.str();
} // autoNamespacePrefix
ScopeStack prefixStack_;
ScopeStack uriStack_;
std::string EMPTY_STRING;
unsigned int autoNs_;
}; // class NamespaceStack
} // namespace XSLT
} // namespace Arabica
#endif // ARABICA_XSLT_NAMESPACE_STACK_HPP