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