1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtXmlPatterns module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | #include <QtDebug> |
41 | |
42 | #include "private/qxmlutils_p.h" |
43 | #include "qxpathhelper_p.h" |
44 | |
45 | #include "qnamepool_p.h" |
46 | |
47 | QT_BEGIN_NAMESPACE |
48 | |
49 | using namespace QPatternist; |
50 | |
51 | NamePool::NamePool() |
52 | { |
53 | m_localNameMapping .reserve(asize: DefaultLocalNameCapacity + StandardLocalNameCount); |
54 | m_localNames .reserve(asize: DefaultLocalNameCapacity + StandardLocalNameCount); |
55 | m_namespaceMapping .reserve(asize: DefaultURICapacity + StandardNamespaceCount); |
56 | m_namespaces .reserve(asize: DefaultURICapacity + StandardNamespaceCount); |
57 | m_prefixes .reserve(asize: DefaultPrefixCapacity + StandardPrefixCount); |
58 | m_prefixMapping .reserve(asize: DefaultPrefixCapacity + StandardPrefixCount); |
59 | |
60 | /* Namespaces. */ |
61 | { |
62 | unlockedAllocateNamespace(uri: QString()); |
63 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2005/xpath-functions" )); |
64 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2005/xquery-local-functions" )); |
65 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/XML/1998/namespace" )); |
66 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2000/xmlns/" )); |
67 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2001/XMLSchema" )); |
68 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/2001/XMLSchema-instance" )); |
69 | unlockedAllocateNamespace(uri: QLatin1String("http://www.w3.org/1999/XSL/Transform" )); |
70 | |
71 | /* For UndeclarePrefix, StopNamespaceInheritance and InternalXSLT. We use two |
72 | * arbitrary strings that aren't used. For instance, if we just used an |
73 | * empty QString, unlockedAllocateNamespace() would assign it |
74 | * StandardNamespaces::empty. However, it's important that the string |
75 | * is an invalid namespace, since otherwise user strings would get |
76 | * assigned the same IDs. */ |
77 | unlockedAllocateNamespace(uri: QLatin1String(" | 1 " )); |
78 | unlockedAllocateNamespace(uri: QLatin1String(" | 2 " )); |
79 | unlockedAllocateNamespace(uri: QLatin1String(" | InternalXSLT" )); |
80 | |
81 | Q_ASSERT_X(m_namespaces.count() == StandardNamespaceCount, Q_FUNC_INFO, |
82 | qPrintable(QString::fromLatin1("Expected is %1, actual is %2." ).arg(StandardNamespaceCount).arg(m_namespaces.count()))); |
83 | } |
84 | |
85 | /* Prefixes. */ |
86 | { |
87 | unlockedAllocatePrefix(prefix: QString()); |
88 | unlockedAllocatePrefix(prefix: QLatin1String("fn" )); |
89 | unlockedAllocatePrefix(prefix: QLatin1String("local" )); |
90 | unlockedAllocatePrefix(prefix: QLatin1String("xml" )); |
91 | unlockedAllocatePrefix(prefix: QLatin1String("xmlns" )); |
92 | unlockedAllocatePrefix(prefix: QLatin1String("xs" )); |
93 | unlockedAllocatePrefix(prefix: QLatin1String("xsi" )); |
94 | unlockedAllocatePrefix(prefix: QLatin1String("ns0" )); |
95 | unlockedAllocatePrefix(prefix: QLatin1String("|||" )); /* Invalid NCName, for StopNamespaceInheritance. */ |
96 | |
97 | Q_ASSERT_X(m_prefixes.count() == StandardPrefixCount, Q_FUNC_INFO, |
98 | qPrintable(QString::fromLatin1("Expected is %1, actual is %2." ).arg(StandardPrefixCount).arg(m_prefixes.count()))); |
99 | } |
100 | |
101 | /* Local names. */ |
102 | { |
103 | /* Same order as the enum in StandardLocalNames. That is, alphabetically. */ |
104 | unlockedAllocateLocalName(ln: QLatin1String("abs" )); |
105 | unlockedAllocateLocalName(ln: QLatin1String("adjust-dateTime-to-timezone" )); |
106 | unlockedAllocateLocalName(ln: QLatin1String("adjust-date-to-timezone" )); |
107 | unlockedAllocateLocalName(ln: QLatin1String("adjust-time-to-timezone" )); |
108 | unlockedAllocateLocalName(ln: QLatin1String("all" )); |
109 | unlockedAllocateLocalName(ln: QLatin1String("arity" )); |
110 | unlockedAllocateLocalName(ln: QLatin1String("avg" )); |
111 | unlockedAllocateLocalName(ln: QLatin1String("base" )); |
112 | unlockedAllocateLocalName(ln: QLatin1String("base-uri" )); |
113 | unlockedAllocateLocalName(ln: QLatin1String("boolean" )); |
114 | unlockedAllocateLocalName(ln: QLatin1String("ceiling" )); |
115 | unlockedAllocateLocalName(ln: QLatin1String("codepoint-equal" )); |
116 | unlockedAllocateLocalName(ln: QLatin1String("codepoints-to-string" )); |
117 | unlockedAllocateLocalName(ln: QLatin1String("collection" )); |
118 | unlockedAllocateLocalName(ln: QLatin1String("compare" )); |
119 | unlockedAllocateLocalName(ln: QLatin1String("concat" )); |
120 | unlockedAllocateLocalName(ln: QLatin1String("contains" )); |
121 | unlockedAllocateLocalName(ln: QLatin1String("count" )); |
122 | unlockedAllocateLocalName(ln: QLatin1String("current" )); |
123 | unlockedAllocateLocalName(ln: QLatin1String("current-date" )); |
124 | unlockedAllocateLocalName(ln: QLatin1String("current-dateTime" )); |
125 | unlockedAllocateLocalName(ln: QLatin1String("current-time" )); |
126 | unlockedAllocateLocalName(ln: QLatin1String("data" )); |
127 | unlockedAllocateLocalName(ln: QLatin1String("dateTime" )); |
128 | unlockedAllocateLocalName(ln: QLatin1String("day-from-date" )); |
129 | unlockedAllocateLocalName(ln: QLatin1String("day-from-dateTime" )); |
130 | unlockedAllocateLocalName(ln: QLatin1String("days-from-duration" )); |
131 | unlockedAllocateLocalName(ln: QLatin1String("deep-equal" )); |
132 | unlockedAllocateLocalName(ln: QLatin1String("default" )); |
133 | unlockedAllocateLocalName(ln: QLatin1String("default-collation" )); |
134 | unlockedAllocateLocalName(ln: QLatin1String("distinct-values" )); |
135 | unlockedAllocateLocalName(ln: QLatin1String("doc" )); |
136 | unlockedAllocateLocalName(ln: QLatin1String("doc-available" )); |
137 | unlockedAllocateLocalName(ln: QLatin1String("document" )); |
138 | unlockedAllocateLocalName(ln: QLatin1String("document-uri" )); |
139 | unlockedAllocateLocalName(ln: QLatin1String("element-available" )); |
140 | unlockedAllocateLocalName(ln: QLatin1String("empty" )); |
141 | unlockedAllocateLocalName(ln: QLatin1String("encode-for-uri" )); |
142 | unlockedAllocateLocalName(ln: QLatin1String("ends-with" )); |
143 | unlockedAllocateLocalName(ln: QLatin1String("error" )); |
144 | unlockedAllocateLocalName(ln: QLatin1String("escape-html-uri" )); |
145 | unlockedAllocateLocalName(ln: QLatin1String("exactly-one" )); |
146 | unlockedAllocateLocalName(ln: QLatin1String("exists" )); |
147 | unlockedAllocateLocalName(ln: QLatin1String("false" )); |
148 | unlockedAllocateLocalName(ln: QLatin1String("floor" )); |
149 | unlockedAllocateLocalName(ln: QLatin1String("function-available" )); |
150 | unlockedAllocateLocalName(ln: QLatin1String("function-name" )); |
151 | unlockedAllocateLocalName(ln: QLatin1String("generate-id" )); |
152 | unlockedAllocateLocalName(ln: QLatin1String("generic-string-join" )); |
153 | unlockedAllocateLocalName(ln: QLatin1String("hours-from-dateTime" )); |
154 | unlockedAllocateLocalName(ln: QLatin1String("hours-from-duration" )); |
155 | unlockedAllocateLocalName(ln: QLatin1String("hours-from-time" )); |
156 | unlockedAllocateLocalName(ln: QLatin1String("id" )); |
157 | unlockedAllocateLocalName(ln: QLatin1String("idref" )); |
158 | unlockedAllocateLocalName(ln: QLatin1String("implicit-timezone" )); |
159 | unlockedAllocateLocalName(ln: QLatin1String("index-of" )); |
160 | unlockedAllocateLocalName(ln: QLatin1String("in-scope-prefixes" )); |
161 | unlockedAllocateLocalName(ln: QLatin1String("insert-before" )); |
162 | unlockedAllocateLocalName(ln: QLatin1String("iri-to-uri" )); |
163 | unlockedAllocateLocalName(ln: QLatin1String("is-schema-aware" )); |
164 | unlockedAllocateLocalName(ln: QLatin1String("key" )); |
165 | unlockedAllocateLocalName(ln: QLatin1String("lang" )); |
166 | unlockedAllocateLocalName(ln: QLatin1String("last" )); |
167 | unlockedAllocateLocalName(ln: QLatin1String("local-name" )); |
168 | unlockedAllocateLocalName(ln: QLatin1String("local-name-from-QName" )); |
169 | unlockedAllocateLocalName(ln: QLatin1String("lower-case" )); |
170 | unlockedAllocateLocalName(ln: QLatin1String("matches" )); |
171 | unlockedAllocateLocalName(ln: QLatin1String("max" )); |
172 | unlockedAllocateLocalName(ln: QLatin1String("min" )); |
173 | unlockedAllocateLocalName(ln: QLatin1String("minutes-from-dateTime" )); |
174 | unlockedAllocateLocalName(ln: QLatin1String("minutes-from-duration" )); |
175 | unlockedAllocateLocalName(ln: QLatin1String("minutes-from-time" )); |
176 | unlockedAllocateLocalName(ln: QLatin1String("month-from-date" )); |
177 | unlockedAllocateLocalName(ln: QLatin1String("month-from-dateTime" )); |
178 | unlockedAllocateLocalName(ln: QLatin1String("months-from-duration" )); |
179 | unlockedAllocateLocalName(ln: QLatin1String("name" )); |
180 | unlockedAllocateLocalName(ln: QLatin1String("namespace-uri" )); |
181 | unlockedAllocateLocalName(ln: QLatin1String("namespace-uri-for-prefix" )); |
182 | unlockedAllocateLocalName(ln: QLatin1String("namespace-uri-from-QName" )); |
183 | unlockedAllocateLocalName(ln: QLatin1String("nilled" )); |
184 | unlockedAllocateLocalName(ln: QLatin1String("node-name" )); |
185 | unlockedAllocateLocalName(ln: QLatin1String("normalize-space" )); |
186 | unlockedAllocateLocalName(ln: QLatin1String("normalize-unicode" )); |
187 | unlockedAllocateLocalName(ln: QLatin1String("not" )); |
188 | unlockedAllocateLocalName(ln: QLatin1String("number" )); |
189 | unlockedAllocateLocalName(ln: QLatin1String("one-or-more" )); |
190 | unlockedAllocateLocalName(ln: QLatin1String("position" )); |
191 | unlockedAllocateLocalName(ln: QLatin1String("prefix-from-QName" )); |
192 | unlockedAllocateLocalName(ln: QLatin1String("product-name" )); |
193 | unlockedAllocateLocalName(ln: QLatin1String("product-version" )); |
194 | unlockedAllocateLocalName(ln: QLatin1String("property-name" )); |
195 | unlockedAllocateLocalName(ln: QLatin1String("QName" )); |
196 | unlockedAllocateLocalName(ln: QLatin1String("remove" )); |
197 | unlockedAllocateLocalName(ln: QLatin1String("replace" )); |
198 | unlockedAllocateLocalName(ln: QLatin1String("resolve-QName" )); |
199 | unlockedAllocateLocalName(ln: QLatin1String("resolve-uri" )); |
200 | unlockedAllocateLocalName(ln: QLatin1String("reverse" )); |
201 | unlockedAllocateLocalName(ln: QLatin1String("root" )); |
202 | unlockedAllocateLocalName(ln: QLatin1String("round" )); |
203 | unlockedAllocateLocalName(ln: QLatin1String("round-half-to-even" )); |
204 | unlockedAllocateLocalName(ln: QLatin1String("seconds-from-dateTime" )); |
205 | unlockedAllocateLocalName(ln: QLatin1String("seconds-from-duration" )); |
206 | unlockedAllocateLocalName(ln: QLatin1String("seconds-from-time" )); |
207 | unlockedAllocateLocalName(ln: QLatin1String("sourceValue" )); |
208 | unlockedAllocateLocalName(ln: QLatin1String("starts-with" )); |
209 | unlockedAllocateLocalName(ln: QLatin1String("static-base-uri" )); |
210 | unlockedAllocateLocalName(ln: QLatin1String("string" )); |
211 | unlockedAllocateLocalName(ln: QLatin1String("string-join" )); |
212 | unlockedAllocateLocalName(ln: QLatin1String("string-length" )); |
213 | unlockedAllocateLocalName(ln: QLatin1String("string-to-codepoints" )); |
214 | unlockedAllocateLocalName(ln: QLatin1String("subsequence" )); |
215 | unlockedAllocateLocalName(ln: QLatin1String("substring" )); |
216 | unlockedAllocateLocalName(ln: QLatin1String("substring-after" )); |
217 | unlockedAllocateLocalName(ln: QLatin1String("substring-before" )); |
218 | unlockedAllocateLocalName(ln: QLatin1String("sum" )); |
219 | unlockedAllocateLocalName(ln: QLatin1String("supports-backwards-compatibility" )); |
220 | unlockedAllocateLocalName(ln: QLatin1String("supports-serialization" )); |
221 | unlockedAllocateLocalName(ln: QLatin1String("system-property" )); |
222 | unlockedAllocateLocalName(ln: QLatin1String("timezone-from-date" )); |
223 | unlockedAllocateLocalName(ln: QLatin1String("timezone-from-dateTime" )); |
224 | unlockedAllocateLocalName(ln: QLatin1String("timezone-from-time" )); |
225 | unlockedAllocateLocalName(ln: QLatin1String("tokenize" )); |
226 | unlockedAllocateLocalName(ln: QLatin1String("trace" )); |
227 | unlockedAllocateLocalName(ln: QLatin1String("translate" )); |
228 | unlockedAllocateLocalName(ln: QLatin1String("true" )); |
229 | unlockedAllocateLocalName(ln: QLatin1String("type-available" )); |
230 | unlockedAllocateLocalName(ln: QLatin1String("unordered" )); |
231 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-entity-public-id" )); |
232 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-entity-uri" )); |
233 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-text" )); |
234 | unlockedAllocateLocalName(ln: QLatin1String("unparsed-text-available" )); |
235 | unlockedAllocateLocalName(ln: QLatin1String("upper-case" )); |
236 | unlockedAllocateLocalName(ln: QLatin1String("vendor" )); |
237 | unlockedAllocateLocalName(ln: QLatin1String("vendor-url" )); |
238 | unlockedAllocateLocalName(ln: QLatin1String("version" )); |
239 | unlockedAllocateLocalName(ln: QLatin1String("xml" )); |
240 | unlockedAllocateLocalName(ln: QLatin1String("xmlns" )); |
241 | unlockedAllocateLocalName(ln: QLatin1String("year-from-date" )); |
242 | unlockedAllocateLocalName(ln: QLatin1String("year-from-dateTime" )); |
243 | unlockedAllocateLocalName(ln: QLatin1String("years-from-duration" )); |
244 | unlockedAllocateLocalName(ln: QLatin1String("zero-or-one" )); |
245 | Q_ASSERT(m_localNames.count() == StandardLocalNameCount); |
246 | } |
247 | } |
248 | |
249 | QXmlName NamePool::allocateQName(const QString &uri, const QString &localName, const QString &prefix) |
250 | { |
251 | QWriteLocker l(&lock); |
252 | |
253 | /* |
254 | QString codepoints; |
255 | for(int i = 0; i < localName.length(); ++i) |
256 | codepoints.append(QString::number(localName.at(i).unicode()) + QLatin1Char(' ')); |
257 | |
258 | pDebug() << Q_FUNC_INFO << localName << "codepoints:" << codepoints; |
259 | */ |
260 | |
261 | Q_ASSERT_X(QXmlUtils::isNCName(localName), Q_FUNC_INFO, |
262 | qPrintable(QString::fromLatin1("'%1' is an invalid NCName." ).arg(localName))); |
263 | |
264 | const QXmlName::NamespaceCode nsCode = unlockedAllocateNamespace(uri); |
265 | const QXmlName::LocalNameCode localCode = unlockedAllocateLocalName(ln: localName); |
266 | |
267 | Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix)); |
268 | const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix); |
269 | |
270 | return QXmlName(nsCode, localCode, prefixCode); |
271 | } |
272 | |
273 | QXmlName NamePool::allocateBinding(const QString &prefix, const QString &uri) |
274 | { |
275 | QWriteLocker l(&lock); |
276 | |
277 | Q_ASSERT_X(prefix.isEmpty() || QXmlUtils::isNCName(prefix), Q_FUNC_INFO, |
278 | qPrintable(QString::fromLatin1("%1 is an invalid prefix." ).arg(prefix))); |
279 | const QXmlName::NamespaceCode nsCode = unlockedAllocateNamespace(uri); |
280 | |
281 | Q_ASSERT(prefix.isEmpty() || QXmlUtils::isNCName(prefix)); |
282 | const QXmlName::PrefixCode prefixCode = unlockedAllocatePrefix(prefix); |
283 | |
284 | return QXmlName(nsCode, StandardLocalNames::empty, prefixCode); |
285 | } |
286 | |
287 | QXmlName::LocalNameCode NamePool::unlockedAllocateLocalName(const QString &ln) |
288 | { |
289 | Q_ASSERT_X(QXmlUtils::isNCName(ln), Q_FUNC_INFO, |
290 | qPrintable(QString::fromLatin1("Invalid local name: \"%1\"" ).arg(ln))); |
291 | |
292 | int indexInLocalNames = m_localNameMapping.value(akey: ln, adefaultValue: NoSuchValue); |
293 | |
294 | if(indexInLocalNames == NoSuchValue) |
295 | { |
296 | indexInLocalNames = m_localNames.count(); |
297 | m_localNames.append(t: ln); |
298 | m_localNameMapping.insert(akey: ln, avalue: indexInLocalNames); |
299 | } |
300 | |
301 | return indexInLocalNames; |
302 | } |
303 | |
304 | QXmlName::PrefixCode NamePool::unlockedAllocatePrefix(const QString &prefix) |
305 | { |
306 | int indexInPrefixes = m_prefixMapping.value(akey: prefix, adefaultValue: NoSuchValue); |
307 | |
308 | if(indexInPrefixes == NoSuchValue) |
309 | { |
310 | indexInPrefixes = m_prefixes.count(); |
311 | m_prefixes.append(t: prefix); |
312 | m_prefixMapping.insert(akey: prefix, avalue: indexInPrefixes); |
313 | } |
314 | |
315 | return indexInPrefixes; |
316 | } |
317 | |
318 | QXmlName::NamespaceCode NamePool::unlockedAllocateNamespace(const QString &uri) |
319 | { |
320 | int indexInURIs = m_namespaceMapping.value(akey: uri, adefaultValue: NoSuchValue); |
321 | |
322 | if(indexInURIs == NoSuchValue) |
323 | { |
324 | indexInURIs = m_namespaces.count(); |
325 | m_namespaces.append(t: uri); |
326 | m_namespaceMapping.insert(akey: uri, avalue: indexInURIs); |
327 | } |
328 | |
329 | return indexInURIs; |
330 | } |
331 | |
332 | const QString &NamePool::displayPrefix(const QXmlName::NamespaceCode nc) const |
333 | { |
334 | switch(nc) |
335 | { |
336 | case StandardNamespaces::xmlns: return m_prefixes.at(i: StandardPrefixes::xmlns); |
337 | case StandardNamespaces::local: return m_prefixes.at(i: StandardPrefixes::local); |
338 | case StandardNamespaces::xs: return m_prefixes.at(i: StandardPrefixes::xs); |
339 | case StandardNamespaces::xml: return m_prefixes.at(i: StandardPrefixes::xml); |
340 | case StandardNamespaces::fn: return m_prefixes.at(i: StandardPrefixes::fn); |
341 | default: return m_prefixes.at(i: StandardPrefixes::empty); |
342 | } |
343 | } |
344 | |
345 | QString NamePool::displayName(const QXmlName qName) const |
346 | { |
347 | QReadLocker l(&lock); |
348 | |
349 | if(qName.hasNamespace()) |
350 | { |
351 | if(qName.namespaceURI() == StandardNamespaces::InternalXSLT) |
352 | return QLatin1Char('#') + m_localNames.at(i: qName.localName()); |
353 | |
354 | const QString &p = displayPrefix(nc: qName.namespaceURI()); |
355 | |
356 | if(p.isEmpty()) |
357 | return QLatin1Char('{') + m_namespaces.at(i: qName.namespaceURI()) + QLatin1Char('}') + toLexical(qName); |
358 | else |
359 | return p + QLatin1Char(':') + m_localNames.at(i: qName.localName()); |
360 | } |
361 | else |
362 | return m_localNames.at(i: qName.localName()); |
363 | } |
364 | |
365 | QString NamePool::toClarkName(const QXmlName &name) const |
366 | { |
367 | if(name.isNull()) |
368 | return QLatin1String("QXmlName(null)" ); |
369 | else |
370 | { |
371 | if(name.hasNamespace()) |
372 | { |
373 | const QString ns(stringForNamespace(code: name.namespaceURI())); |
374 | const QString p(stringForPrefix(code: name.prefix())); |
375 | const QString l(stringForLocalName(code: name.localName())); |
376 | |
377 | return QChar::fromLatin1(c: '{') |
378 | + ns |
379 | + QChar::fromLatin1(c: '}') |
380 | + (p.isEmpty() ? l : p + QChar::fromLatin1(c: ':') + l); |
381 | } |
382 | else |
383 | return stringForLocalName(code: name.localName()); |
384 | } |
385 | } |
386 | |
387 | QXmlName NamePool::fromClarkName(const QString &clarkName) |
388 | { |
389 | if(clarkName.isEmpty()) |
390 | return QXmlName(); |
391 | |
392 | if(clarkName.at(i: 0) == QLatin1Char('{')) |
393 | { |
394 | const int indexOfRight = clarkName.indexOf(c: QLatin1Char('}')); |
395 | const QString qName(clarkName.right(n: (clarkName.length() - indexOfRight) - 1)); |
396 | |
397 | if(!XPathHelper::isQName(qName)) |
398 | return QXmlName(); |
399 | |
400 | QString localName; |
401 | QString prefix; |
402 | |
403 | XPathHelper::splitQName(qName, prefix, localName); |
404 | |
405 | return allocateQName(uri: clarkName.mid(position: 1, n: indexOfRight - 1), |
406 | localName, prefix); |
407 | } |
408 | else |
409 | { |
410 | if(QXmlName::isNCName(candidate: clarkName)) |
411 | return allocateQName(uri: QString(), localName: clarkName); |
412 | else |
413 | return QXmlName(); |
414 | } |
415 | } |
416 | QT_END_NAMESPACE |
417 | |