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/*
41 * QXmlName is conceptually identical to QPatternist::QName. The
42 * difference is that the latter is elegant, powerful and fast.
43 *
44 * However, it is too powerful and too open and not at all designed
45 * for being public. QXmlName, in contrast, is only a public marker,
46 * that for instance uses a qint64 instead of qint32, such that we in
47 * the future can use that, if needed.
48 */
49
50#include "qnamepool_p.h"
51#include "qxmlname.h"
52#include "qxmlnamepool.h"
53#include "qxpathhelper_p.h"
54#include "private/qxmlutils_p.h"
55
56QT_BEGIN_NAMESPACE
57
58/*!
59 \class QXmlName
60 \brief The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way.
61 \reentrant
62 \since 4.4
63 \ingroup xml-tools
64 \inmodule QtXmlPatterns
65 QXmlName represents the name of an XML node in a way that
66 is both efficient and safe for comparing names. Normally,
67 an XML node represents an XML element or attribute, but
68 QXmlName can also represent the names of other kinds of
69 nodes, e.g., QAbstractXmlReceiver::processingInstruction()
70 and QAbstractXmlReceiver::namespaceBinding().
71
72 The name of an XML node has three components: The \e {namespace
73 URI}, the \e {local name}, and the \e {prefix}. To see what these
74 refer to in XML, consider the following snippet.
75
76 \quotefile patternist/mobeyDick.xml
77
78 For the element named \e book, localName() returns \e book,
79 namespaceUri() returns \e http://example.com/MyDefault,
80 and prefix() returns an empty string. For the element named
81 \e title, localName() returns \e title, namespaceUri() returns
82 \e http://purl.org/dc/elements/1.1, and prefix() returns \e dc.
83
84 To ensure that operations with QXmlName are efficient, e.g.,
85 copying names and comparing them, each instance of QXmlName is
86 associated with a \l {QXmlNamePool} {name pool}, which must be
87 specified at QXmlName construction time. The three components
88 of the QXmlName, i.e., the namespace URI, the local name, and
89 the prefix, are stored in the name pool mapped to identifiers
90 so they can be shared. For this reason, the only way to create
91 a valid instance of QXmlName is to use the class constructor,
92 where the \l {QXmlNamePool} {name pool}, local name, namespace
93 URI, and prefix must all be specified.
94
95 Note that QXmlName's default constructor constructs a null
96 instance. It is typically used for allocating unused entries
97 in collections of QXmlName.
98
99 A side effect of associating each instance of QXmlName with
100 a \l {QXmlNamePool} {name pool} is that each instance of
101 QXmlName is tied to the QXmlNamePool with which it was created.
102 However, the QXmlName class does not keep track of the name pool,
103 so all the accessor functions, e.g., namespaceUri(), prefix(),
104 localName(), and toClarkName() require that the correct name
105 pool be passed to them. Failure to provide the correct name
106 pool to these accessor functions results in undefined behavior.
107
108 Note that a \l {QXmlNamePool} {name pool} is \e not an XML
109 namespace. One \l {QXmlNamePool} {name pool} can represent
110 instances of QXmlName from different XML namespaces, and the
111 instances of QXmlName from one XML namespace can be distributed
112 over multiple \l {QXmlNamePool} {name pools}.
113
114 \target Comparing QXmlNames
115 \section1 Comparing QXmlNames
116
117 To determine what a QXmlName refers to, the \e {namespace URI}
118 and the \e {local name} are used. The \e prefix is not used
119 because the prefix is simply a shorthand name for use in place
120 of the normally much longer namespace URI. Nor is the prefix
121 used in name comparisons. For example, the following two element
122 nodes represent the same element and compare equal.
123
124 \quotefile patternist/svgDocumentElement.xml
125
126 \quotefile patternist/xsvgDocumentElement.xml
127
128 Although the second name has the prefix \e x, the two names compare
129 equal as instances of QXmlName, because the prefix is not used in
130 the comparison.
131
132 A local name can never be an empty string, although the prefix and
133 namespace URI can. If the prefix is not empty, the namespace URI
134 cannot be empty. Local names and prefixes must be valid
135 \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {NCNames},
136 e.g., \e abc.def or \e abc123.
137
138 QXmlName represents what is sometimes called an \e {expanded QName},
139 or simply a QName.
140
141 \sa {http://www.w3.org/TR/REC-xml-names/#NT-NCName}{Namespaces in XML 1.0 (Second Edition), [4] NCName}
142 */
143
144/*!
145 \enum QXmlName::Constant
146 \internal
147 Various constants used in the QPatternist::NamePool and QXmlName.
148
149 Setting of the mask enums use essentially this:
150
151 \quotefile code/src_xmlpatterns_api_qxmlname.cpp
152
153 The masks, such as LocalNameMask, are positive. That is, for the
154 area which the name resides, the bits are set.
155 */
156
157/*!
158 Constructs a QXmlName instance that inserts \a localName,
159 \a namespaceURI and \a prefix into \a namePool if they aren't
160 already there. The accessor functions namespaceUri(), prefix(),
161 localName(), and toClarkName() must be passed the \a namePool
162 used here, so the \a namePool must remain in scope while the
163 accessor functions might be used. However, two instances can
164 be compared with \e {==} or \e {!=} and copied without the
165 \a namePool.
166
167 The user guarantees that the string components are valid for a
168 QName. In particular, the local name, and the prefix (if present),
169 must be valid \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName}
170 {NCNames}. The function isNCName() can be used to test validity
171 of these names. The namespace URI should be an absolute URI.
172 QUrl::isRelative() can be used to test whether the namespace URI
173 is relative or absolute. Finally, providing a prefix is not valid
174 when no namespace URI is provided.
175
176 \a namePool is not copied. Nor is the reference to it retained
177 in this instance. This constructor inserts the three strings
178 into \a namePool.
179 */
180QXmlName::QXmlName(QXmlNamePool &namePool,
181 const QString &localName,
182 const QString &namespaceURI,
183 const QString &prefix)
184{
185 Q_ASSERT_X(prefix.isEmpty() || QXmlUtils::isNCName(prefix), Q_FUNC_INFO,
186 "The prefix is invalid, maybe the arguments were mixed up?");
187 Q_ASSERT_X(QXmlUtils::isNCName(localName), Q_FUNC_INFO,
188 "The local name is invalid, maybe the arguments were mixed up?");
189
190 m_qNameCode = namePool.d->allocateQName(uri: namespaceURI, localName, prefix).code();
191}
192
193/*!
194 \typedef QXmlName::Code
195 \internal
196
197 Stores the \l {QXmlNamePool} {name pool} identifiers for
198 the namespace URI, local name, and prefix.
199 */
200
201/*!
202 Returns true if this QXmlName is not initialized with a
203 valid combination of \e {namespace URI}, \e {local name},
204 and \e {prefix}.
205
206 A valid local name is always required. The prefix and
207 namespace URI can be empty, but if the prefix is not empty,
208 the namespace URI must not be empty. Local names and
209 prefixes must be valid
210 \l {http://www.w3.org/TR/REC-xml-names/#NT-NCName} {NCNames},
211 e.g., \e abc.def or \e abc123.
212 */
213bool QXmlName::isNull() const
214{
215 return m_qNameCode == InvalidCode;
216}
217
218/*!
219 Constructs an uninitialized QXmlName. To build
220 a valid QXmlName, you normally use the other constructor, which
221 takes a \l {QXmlNamePool} {name pool}, namespace URI, local name,
222 and prefix as parameters. But you can also use this constructor
223 to build a null QXmlName and then assign an existing QXmlName
224 to it.
225
226 \sa isNull()
227 */
228QXmlName::QXmlName() : m_qNameCode(InvalidCode)
229{
230}
231
232/*!
233 \fn QXmlName::QXmlName(const NamespaceCode uri,
234 const LocalNameCode ln,
235 const PrefixCode p = 0)
236 \internal
237 */
238
239/*!
240 \fn QXmlName::hasPrefix() const
241 \internal
242
243 Returns true if this QXmlName has a non-empty prefix. If this
244 function returns true, hasNamespace() will also return true,
245 because a QXmlName can't have a prefix if it doesn't have a
246 namespace URI.
247 */
248
249/*!
250 \fn bool QXmlName::hasNamespace() const
251 \internal
252
253 Returns true if this QXmlName has a non-empty namespace URI.
254 */
255
256/*!
257 \fn Code QXmlName::code() const
258 \internal
259
260 Returns the internal code that contains the id codes for the
261 local name, prefix and namespace URI. It is opaque when used
262 outside QXmlName, but it can be useful when one wants to put
263 a QXmlName in a hash, and the prefix is significant.
264 */
265
266/*!
267 Returns true if this QXmlName is equal to \a other; otherwise false.
268 Two QXmlNames are equal if their namespace URIs are the same \e and
269 their local names are the same. The prefixes are ignored.
270
271 Note that it is meaningless to compare two instances of QXmlName
272 that were created with different \l {QXmlNamePool} {name pools},
273 but the attempt is not detected and the behavior is undefined.
274
275 \sa operator!=()
276 */
277bool QXmlName::operator==(const QXmlName &other) const
278{
279 return (m_qNameCode & ExpandedNameMask) == (other.m_qNameCode & ExpandedNameMask);
280}
281
282/*!
283 Returns true if this QXmlName is \e not equal to \a other;
284 otherwise false. Two QXmlNames are equal if their namespace
285 URIs are the same \e and their local names are the same. They
286 are not equal if either their namespace URIs differ or their
287 local names differ. Their prefixes are ignored.
288
289 Note that it is meaningless to compare two instances of QXmlName
290 that were created with different \l {QXmlNamePool} {name pools},
291 but the attempt is not detected and the behavior is undefined.
292
293 \sa operator==()
294 */
295bool QXmlName::operator!=(const QXmlName &other) const
296{
297 return !operator==(other);
298}
299
300/*!
301 \fn bool QXmlName::isLexicallyEqual(const QXmlName &other) const
302 \internal
303
304 Returns true if this and \a other are lexically equal. Two
305 QXmlNames are lexically equal if their local names are equal
306 \e and their prefixes are equal.
307 */
308
309/*!
310 \fn uint qHash(const QXmlName &name)
311 \since 4.4
312 \relates QXmlName
313
314 Computes a hash key from the local name and the namespace
315 URI in \a name. The prefix in \a name is not used in the computation.
316 */
317uint qHash(const QXmlName &name)
318{
319 return name.m_qNameCode & QXmlName::ExpandedNameMask;
320}
321
322/*!
323 Returns the namespace URI.
324
325 Note that for efficiency, the namespace URI string is not
326 stored in the QXmlName but in the \l {QXmlNamePool} that was
327 passed to the constructor. Hence, that same \a namePool must
328 be passed to this function, so it can be used for looking up
329 the namespace URI.
330 */
331QString QXmlName::namespaceUri(const QXmlNamePool &namePool) const
332{
333 if(isNull())
334 return QString();
335 else
336 return namePool.d->stringForNamespace(code: namespaceURI());
337}
338
339/*!
340 Returns the prefix.
341
342 Note that for efficiency, the prefix string is not stored in
343 the QXmlName but in the \l {QXmlNamePool} that was passed to
344 the constructor. Hence, that same \a namePool must be passed
345 to this function, so it can be used for looking up the prefix.
346 */
347QString QXmlName::prefix(const QXmlNamePool &namePool) const
348{
349 if(isNull())
350 return QString();
351 else
352 return namePool.d->stringForPrefix(code: prefix());
353}
354
355/*!
356 Returns the local name.
357
358 Note that for efficiency, the local name string is not stored
359 in the QXmlName but in the \l {QXmlNamePool} that was passed to
360 the constructor. Hence, that same \a namePool must be passed
361 to this function, so it can be used for looking up the
362 local name.
363 */
364QString QXmlName::localName(const QXmlNamePool &namePool) const
365{
366 if(isNull())
367 return QString();
368 else
369 return namePool.d->stringForLocalName(code: localName());
370}
371
372/*!
373 Returns this QXmlName formatted as a Clark Name. For example,
374 if the local name is \c html, the prefix is \c x, and the
375 namespace URI is \c {http://www.w3.org/1999/xhtml/},
376 then the Clark Name returned is:
377
378 \code
379 {http://www.w3.org/1999/xhtml/}x:html.
380 \endcode
381
382 If the local name is \e {MyWidget} and the namespace is empty,
383 the Clark Name returned is:
384
385 \code
386 MyWidget
387 \endcode
388
389 Note that for efficiency, the namespace URI, local name, and
390 prefix strings are not stored in the QXmlName but in the
391 \l {QXmlNamePool} that was passed to the constructor. Hence,
392 that same \a namePool must be passed to this function, so it
393 can be used for looking up the three string components.
394
395 This function can be useful for debugging.
396
397 \sa {http://www.jclark.com/xml/xmlns.htm}{XML Namespaces, James Clark}, fromClarkName()
398 */
399QString QXmlName::toClarkName(const QXmlNamePool &namePool) const
400{
401 return namePool.d->toClarkName(name: *this);
402}
403
404/*!
405 Constructs a copy of \a other.
406
407 \sa operator=()
408 \since 5.9
409*/
410QXmlName::QXmlName(const QXmlName &) = default; // ### Qt 6: remove
411
412/*!
413 Assigns \a other to \e this and returns \e this.
414 */
415QXmlName &QXmlName::operator=(const QXmlName &) = default; // ### Qt 6: remove
416
417/*!
418 Returns true if \a candidate is an \c NCName. An \c NCName
419 is a string that can be used as a name in XML and XQuery,
420 e.g., the prefix or local name in an element or attribute,
421 or the name of a variable.
422
423 \sa {http://www.w3.org/TR/REC-xml-names/#NT-NCName}{Namespaces in XML 1.0 (Second Edition), [4] NCName}
424 */
425bool QXmlName::isNCName(const QString &candidate)
426{
427 return QXmlUtils::isNCName(ncName: candidate);
428}
429
430/*!
431 Converts \a clarkName into a QXmlName, inserts into \a namePool, and
432 returns it.
433
434 A clark name is a way to present a full QName with only one string, where
435 the namespace cannot contain braces. Here are a couple of examples:
436
437 \table
438 \header
439 \li Clark Name
440 \li Description
441 \row
442 \li \c html
443 \li The local name \c html, in no namespace
444 \row
445 \li \c {http://www.w3.org/1999/xhtml}html
446 \li The local name \c html, in the XHTML namespace
447 \row
448 \li \c {http://www.w3.org/1999/xhtml}my:html
449 \li The local name \c html, in the XHTML namespace, with the prefix \c my
450 \endtable
451
452 If the namespace contains braces, the returned value is either invalid or
453 has undefined content.
454
455 If \a clarkName is an invalid name, a default constructed QXmlName is
456 returned.
457
458 \since 4.5
459 \sa toClarkName()
460 */
461QXmlName QXmlName::fromClarkName(const QString &clarkName,
462 const QXmlNamePool &namePool)
463{
464 return namePool.d->fromClarkName(clarkName);
465}
466
467/*!
468 \typedef QXmlName::LocalNameCode
469 \internal
470 */
471
472/*!
473 \typedef QXmlName::PrefixCode
474 \internal
475 */
476
477/*!
478 \typedef QXmlName::NamespaceCode
479 \internal
480 */
481
482/*!
483 \fn void QXmlName::setLocalName(const LocalNameCode c)
484 \internal
485*/
486
487/*!
488 \fn LocalNameCode QXmlName::localName() const
489 \internal
490*/
491
492/*!
493 \fn PrefixCode QXmlName::prefix() const
494 \internal
495*/
496
497/*!
498 \fn NamespaceCode QXmlName::namespaceURI() const
499 \internal
500*/
501
502/*!
503 \fn void QXmlName::setNamespaceURI(const NamespaceCode c)
504 \internal
505*/
506
507/*!
508 \fn void QXmlName::setPrefix(const PrefixCode c)
509 \internal
510*/
511QT_END_NAMESPACE
512
513

source code of qtxmlpatterns/src/xmlpatterns/api/qxmlname.cpp