| 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 | |