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 | |
56 | QT_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 | */ |
180 | QXmlName::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 | */ |
213 | bool 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 | */ |
228 | QXmlName::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 | */ |
277 | bool 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 | */ |
295 | bool 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 | */ |
317 | uint 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 | */ |
331 | QString 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 | */ |
347 | QString 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 | */ |
364 | QString 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 | */ |
399 | QString 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 | */ |
410 | QXmlName::QXmlName(const QXmlName &) = default; // ### Qt 6: remove |
411 | |
412 | /*! |
413 | Assigns \a other to \e this and returns \e this. |
414 | */ |
415 | QXmlName &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 | */ |
425 | bool 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 | */ |
461 | QXmlName 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 | */ |
511 | QT_END_NAMESPACE |
512 | |
513 | |