source: trunk/src/xmlpatterns/api/qxmlname.cpp@ 350

Last change on this file since 350 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 16.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
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
58QT_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 */
182QXmlName::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 */
215bool 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 */
230QXmlName::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 */
279bool 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 */
297bool 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 */
319uint 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 */
333QString 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.