1//
2// NamespaceSupport.cpp
3//
4// Library: XML
5// Package: SAX
6// Module: SAX
7//
8// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/SAX/NamespaceSupport.h"
16#include "Poco/XML/Name.h"
17
18
19namespace Poco {
20namespace XML {
21
22
23const XMLString NamespaceSupport::EMPTY_STRING;
24const XMLString NamespaceSupport::XML_NAMESPACE = toXMLString("http://www.w3.org/XML/1998/namespace");
25const XMLString NamespaceSupport::XML_NAMESPACE_PREFIX = toXMLString("xml");
26const XMLString NamespaceSupport::XMLNS_NAMESPACE = toXMLString("http://www.w3.org/xmlns/2000/");
27const XMLString NamespaceSupport::XMLNS_NAMESPACE_PREFIX = toXMLString("xmlns");
28
29
30NamespaceSupport::NamespaceSupport()
31{
32 reset();
33}
34
35
36NamespaceSupport::~NamespaceSupport()
37{
38}
39
40
41bool NamespaceSupport::declarePrefix(const XMLString& prefix, const XMLString& namespaceURI)
42{
43 poco_assert (_contexts.size() > 0);
44
45 Context& ctx = _contexts.back();
46 if (ctx.find(prefix) == ctx.end())
47 {
48 ctx.insert(Context::value_type(prefix, namespaceURI));
49 return true;
50 }
51 else return false;
52}
53
54
55bool NamespaceSupport::undeclarePrefix(const XMLString& prefix)
56{
57 for (ContextVec::reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit)
58 {
59 Context::iterator it = rit->find(prefix);
60 if (it != rit->end())
61 {
62 rit->erase(it);
63 return true;
64 }
65 }
66 return false;
67}
68
69
70void NamespaceSupport::getDeclaredPrefixes(PrefixSet& prefixes) const
71{
72 prefixes.clear();
73 const Context& ctx = _contexts.back();
74 for (Context::const_iterator it = ctx.begin(); it != ctx.end(); ++it)
75 prefixes.insert(it->first);
76}
77
78
79const XMLString& NamespaceSupport::getPrefix(const XMLString& namespaceURI) const
80{
81 for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit)
82 {
83 for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it)
84 {
85 if (it->second == namespaceURI)
86 return it->first;
87 }
88 }
89 return EMPTY_STRING;
90}
91
92
93bool NamespaceSupport::isMapped(const XMLString& namespaceURI) const
94{
95 for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit)
96 {
97 for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it)
98 {
99 if (it->second == namespaceURI)
100 return true;
101 }
102 }
103 return false;
104}
105
106
107void NamespaceSupport::getPrefixes(PrefixSet& prefixes) const
108{
109 prefixes.clear();
110 for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit)
111 {
112 for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it)
113 {
114 const XMLString& prefix = it->first;
115 if (!prefix.empty() && prefixes.find(prefix) == prefixes.end())
116 prefixes.insert(it->first);
117 }
118 }
119}
120
121
122void NamespaceSupport::getPrefixes(const XMLString& namespaceURI, PrefixSet& prefixes) const
123{
124 prefixes.clear();
125 for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit)
126 {
127 for (Context::const_iterator it = rit->begin(); it != rit->end(); ++it)
128 {
129 const XMLString& prefix = it->first;
130 if (it->second == namespaceURI && !prefix.empty() && prefixes.find(prefix) == prefixes.end())
131 prefixes.insert(it->first);
132 }
133 }
134}
135
136
137const XMLString& NamespaceSupport::getURI(const XMLString& prefix) const
138{
139 for (ContextVec::const_reverse_iterator rit = _contexts.rbegin(); rit != _contexts.rend(); ++rit)
140 {
141 Context::const_iterator it = rit->find(prefix);
142 if (it != rit->end())
143 return it->second;
144 }
145 return EMPTY_STRING;
146}
147
148
149void NamespaceSupport::pushContext()
150{
151 _contexts.push_back(Context());
152}
153
154
155void NamespaceSupport::popContext()
156{
157 _contexts.pop_back();
158}
159
160
161bool NamespaceSupport::processName(const XMLString& qname, XMLString& namespaceURI, XMLString& localName, bool isAttribute) const
162{
163 XMLString prefix;
164 Name::split(qname, prefix, localName);
165 if (prefix.empty() && isAttribute)
166 {
167 namespaceURI.clear();
168 return true;
169 }
170 else
171 {
172 namespaceURI = getURI(prefix);
173 return !namespaceURI.empty() || prefix.empty();
174 }
175}
176
177
178void NamespaceSupport::reset()
179{
180 _contexts.clear();
181 pushContext();
182 declarePrefix(XML_NAMESPACE_PREFIX, XML_NAMESPACE);
183 declarePrefix(XMLNS_NAMESPACE_PREFIX, XMLNS_NAMESPACE);
184}
185
186
187} } // namespace Poco::XML
188