Qt 4.8
qabstractxmlnodemodel.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QVector>
43 
45 #include "qabstractxmlreceiver.h"
46 #include "qcommonvalues_p.h"
47 #include "qemptyiterator_p.h"
48 #include "qitemmappingiterator_p.h"
49 #include "qitem_p.h"
50 #include "qnamespaceresolver_p.h"
52 #include "qsingletoniterator_p.h"
53 
54 #include "qabstractxmlnodemodel.h"
55 
57 
58 using namespace QPatternist;
59 
61 
68 {
69  Q_ASSERT(!n.isNull());
70  const QXmlNodeModelIndex::NodeKind nk = n.kind();
73 }
74 
75 
286 using namespace QPatternist;
287 
292 {
293 }
294 
302 {
303 }
304 
309 {
310 }
311 
412 /*
413 ### Qt 5:
414 
415 Add the function:
416 
417  virtual QSourceLocation sourceLocation(const QXmlNodeModelIndex &nodeIndex) const = 0;
418 
419 Such that the data model can communicate back source locations.
420  */
421 
472 namespace QPatternist
473 {
475  {
476  public:
477  inline MergeIterator()
478  {
479  }
480 
481  inline
484  const DynamicContext::Ptr &) const
485  {
486  return it;
487  }
488 
489  private:
491  };
492 
494 
506  class IteratorVector : public ListIterator<QXmlNodeModelIndexIteratorPointer, QVector<QXmlNodeModelIndexIteratorPointer> >
507  {
509  public:
511 
513  {
514  }
515 
517  {
518  ItVector result;
519 
520  for(int i = 0; i < m_list.count(); ++i)
521  result.append(m_list.at(i)->copy());
522 
523  return Ptr(new IteratorVector(result));
524  }
525  };
526 }
527 
535 {
537  iterators.append(makeSingletonIterator(node));
538  iterators.append(it2);
539 
540  return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
541  IteratorVector::Ptr(new IteratorVector(iterators)),
543 }
544 
547  const DynamicContext::Ptr &) const
548 {
549  Q_ASSERT(!ni.isNull());
550  /* Since we pass in this here, mapToSequence is used recursively. */
551  return mergeIterators(ni, makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
554 }
555 
617  QXmlNodeModelIndex::Axis axis) const
618 {
619  /* Returns iterators that track state and calls nextFromSimpleAxis()
620  * iteratively. Typically, when sub-classing QSimpleXmlNodeModel,
621  * you don't reimplement this function, but instead implement
622  * nextFromSimpleAxis(). */
623 
624  switch(axis)
625  {
627  return makeSingletonIterator(ni);
629  {
631  return makeEmptyIterator<QXmlNodeModelIndex>();
632  else
633  return makeSingletonIterator(nextFromSimpleAxis(Parent, ni));
634  }
636  return makeEmptyIterator<QXmlNodeModelIndex>();
638  {
639  QList<QXmlNodeModelIndex> ancestors;
641 
642  while(!ancestor.isNull())
643  {
644  ancestors.append(ancestor);
645  ancestor = nextFromSimpleAxis(Parent, ancestor);
646  }
647 
648  return makeListIterator(ancestors);
649  }
651  {
652  QList<QXmlNodeModelIndex> ancestors;
653  ancestors.append(ni);
655 
656  while(!ancestor.isNull())
657  {
658  ancestors.append(ancestor);
659  ancestor = nextFromSimpleAxis(Parent, ancestor);
660  }
661 
662  return makeListIterator(ancestors);
663  }
665  {
666  QList<QXmlNodeModelIndex> preceding;
668 
669  while(!sibling.isNull())
670  {
671  preceding.append(sibling);
672  sibling = nextFromSimpleAxis(PreviousSibling, sibling);
673  }
674 
675  return makeListIterator(preceding);
676  }
678  {
679  QList<QXmlNodeModelIndex> preceding;
681 
682  while(!sibling.isNull())
683  {
684  preceding.append(sibling);
685  sibling = nextFromSimpleAxis(NextSibling, sibling);
686  }
687 
688  return makeListIterator(preceding);
689  }
691  {
692  if(nextFromSimpleAxis(Parent, ni).isNull())
693  {
694  switch(kind(ni))
695  {
697  /* Fallthrough. */
699  /* Fallthrough. */
701  /* Fallthrough. */
703  return makeSingletonIterator(ni);
705  /* Fallthrough. */
707  /* Fallthrough. */
709  /* Do nothing. */;
710  }
711  }
712 
713  /* Else, fallthrough to AxisChild. */
714  }
716  {
717  QList<QXmlNodeModelIndex> children;
719 
720  while(!child.isNull())
721  {
722  children.append(child);
723  child = nextFromSimpleAxis(NextSibling, child);
724  }
725 
726  return makeListIterator(children);
727  }
729  {
730  return makeSequenceMappingIterator<QXmlNodeModelIndex>(this,
733  }
735  {
737  return makeSingletonIterator(ni);
738 
739  /* Else, fallthrough to AxisAttribute. */
740  }
742  return makeVectorIterator(attributes(ni));
746  /* Fallthrough. */
748  {
749  /* We walk up along the ancestors, and for each parent, we grab its preceding/following
750  * siblings, and evaluate the descendant axis. The descendant axes gets added
751  * to a list and we then merge those iterators. */
752  QVector<QXmlNodeModelIndexIteratorPointer> descendantIterators;
753 
754  QXmlNodeModelIndex current(ni);
755  while(!current.isNull())
756  {
758  if(candidate.isNull())
759  {
760  /* current is an ancestor. We don't want it, so next iteration we
761  * will grab its preceding sibling. */
762  current = nextFromSimpleAxis(Parent, current);
763  }
764  else
765  {
766  current = candidate;
767  descendantIterators.append(iterate(current, QXmlNodeModelIndex::AxisDescendantOrSelf)->toReversed());
768  }
769  }
770 
771  return makeSequenceMappingIterator<QXmlNodeModelIndex>(&mergeIterator,
772  IteratorVector::Ptr(new IteratorVector(descendantIterators)),
774  }
775  }
776 
777  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown axis, internal error.");
778  return makeEmptyIterator<QXmlNodeModelIndex>();
779 }
780 
921  QAbstractXmlReceiver *const receiver) const
922 {
923  Q_ASSERT(receiver);
924  const QVector<QXmlName> nss(namespaceBindings(n));
925 
926  /* This is by far the most common case. */
927  if(nss.isEmpty())
928  return;
929 
930  const int len = nss.size();
931  for(int i = 0; i < len; ++i)
932  receiver->namespaceBinding(nss.at(i));
933 }
934 
997 {
998  const QVariant &candidate = typedValue(ni);
999  if(candidate.isNull())
1001  else
1002  return makeSingletonIterator(AtomicValue::toXDM(candidate));
1003 }
1004 
1009 {
1010  Q_ASSERT_X(false, Q_FUNC_INFO,
1011  "This function is internal and must not be called.");
1012  return QPatternist::ItemTypePtr();
1013 }
1014 
1035  const QXmlName::PrefixCode prefix) const
1036 {
1038 
1039  const QVector<QXmlName> nbs(namespaceBindings(ni));
1040  const int len = nbs.size();
1041 
1042  for(int i = 0; i < len; ++i)
1043  {
1044  if(nbs.at(i).prefix() == prefix)
1045  return nbs.at(i).namespaceURI();
1046  }
1047 
1048  return NamespaceResolver::NoBinding;
1049 }
1050 
1051 
1072  const QXmlNodeModelIndex &n2) const
1073 {
1074  Q_ASSERT(!n1.isNull());
1075  Q_ASSERT(!n2.isNull());
1076 
1077  const QXmlNodeModelIndex::NodeKind nk = n1.kind();
1078 
1079  if(nk != n2.kind())
1080  return false;
1081 
1082  if(n1.name() != n2.name())
1083  return false;
1084 
1085  switch(nk)
1086  {
1088  {
1090  QXmlNodeModelIndex node(atts1->next());
1091 
1093  const QXmlNodeModelIndex::List::const_iterator end(atts2.constEnd());
1094 
1095  while(!node.isNull())
1096  {
1097  bool equal = false;
1098  for(QXmlNodeModelIndex::List::const_iterator it = atts2.constBegin(); it != end; ++it)
1099  {
1100  if(isDeepEqual(node, (*it)))
1101  equal = true;
1102  }
1103 
1104  if(!equal)
1105  return false;
1106 
1107  node = atts1->next();
1108  }
1109 
1110  /* Fallthrough, so we check the children. */
1111  }
1113  {
1116 
1117  while(true)
1118  {
1119  QXmlNodeModelIndex no1(itn1->next());
1120  QXmlNodeModelIndex no2(itn2->next());
1121 
1122  while(!no1.isNull() && isIgnorableInDeepEqual(no1))
1123  no1 = itn1->next();
1124 
1125  while(!no2.isNull() && isIgnorableInDeepEqual(no2))
1126  no2 = itn2->next();
1127 
1128  if(!no1.isNull() && !no2.isNull())
1129  {
1130  if(!isDeepEqual(no1, no2))
1131  return false;
1132  }
1133  else
1134  return no1.isNull() && no2.isNull();
1135  }
1136 
1137  return true;
1138  }
1140  /* Fallthrough */
1142  /* Fallthrough. */
1144  /* Fallthrough. */
1146  return n1.stringValue() == n2.stringValue();
1148  {
1149  Q_ASSERT_X(false, Q_FUNC_INFO, "Not implemented");
1150  return false;
1151  }
1152  }
1153 
1154  return false;
1155 }
1156 
1208 {
1209  m_node.reset();
1210 }
1211 
1213 {
1214  return m_node.model == reinterpret_cast<QAbstractXmlNodeModel *>(~0);
1215 }
1216 
1220 QXmlItem::QXmlItem(const QXmlItem &other) : m_node(other.m_node)
1221 {
1222  if(internalIsAtomicValue())
1223  m_atomicValue->ref.ref();
1224 }
1225 
1231 QXmlItem::QXmlItem(const QVariant &atomicValue)
1232 {
1233  m_node.reset();
1234  if(atomicValue.isNull())
1235  {
1236  /* Then we behave just like the default constructor. */
1237  return;
1238  }
1239 
1240  /*
1241  We can't assign directly to m_atomicValue, because the
1242  temporary will self-destruct before we've ref'd it.
1243  */
1244  const QPatternist::Item temp(QPatternist::AtomicValue::toXDM(atomicValue));
1245 
1246  if(temp)
1247  {
1248  temp.asAtomicValue()->ref.ref();
1249  m_node.model = reinterpret_cast<const QAbstractXmlNodeModel *>(~0);
1250  m_atomicValue = temp.asAtomicValue();
1251  }
1252  else
1253  {
1254  m_atomicValue = 0;
1255  }
1256 }
1257 
1263 QXmlItem::QXmlItem(const QXmlNodeModelIndex &node) : m_node(node.m_storage)
1264 {
1265 }
1266 
1267 
1272 {
1274  delete m_atomicValue;
1275 }
1276 
1278 {
1279  return data != other.data
1280  || additionalData != other.additionalData
1281  || model != other.model;
1282 }
1283 
1288 {
1289  if(m_node != other.m_node)
1290  {
1292  delete m_atomicValue;
1293 
1294  m_node = other.m_node;
1295 
1296  if(internalIsAtomicValue())
1297  m_atomicValue->ref.ref();
1298  }
1299 
1300  return *this;
1301 }
1302 
1309 bool QXmlItem::isNode() const
1310 {
1311  return QPatternist::Item::fromPublic(*this).isNode();
1312 }
1313 
1321 {
1322  return internalIsAtomicValue();
1323 }
1324 
1335 {
1336  if(isAtomicValue())
1338  else
1339  return QVariant();
1340 }
1341 
1351 {
1352  if(isNode())
1353  return reinterpret_cast<const QXmlNodeModelIndex &>(m_node);
1354  else
1355  return QXmlNodeModelIndex();
1356 }
1357 
1363 bool QXmlItem::isNull() const
1364 {
1365  return !m_node.model;
1366 }
1367 
1448 {
1449  return uint(index.data() + index.additionalData() + quintptr(index.model()));
1450 }
1451 
1487 {
1488  return !(m_storage != other.m_storage);
1489 }
1490 
1495 {
1496  return !(operator==(other));
1497 }
1498 
1725  QAbstractXmlReceiver *const receiver,
1726  const NodeCopySettings &copySettings) const
1727 {
1728  Q_UNUSED(node);
1729  Q_UNUSED(receiver);
1730  Q_UNUSED(copySettings);
1731  Q_ASSERT_X(false, Q_FUNC_INFO,
1732  "This function is not expected to be called.");
1733 }
1734 
1743 {
1744  // TODO: make this method virtual in Qt5 to allow source location support in custom models
1745  if (d_ptr)
1746  return d_ptr->sourceLocation(index);
1747  else
1748  return QSourceLocation();
1749 }
1750 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
virtual QXmlName::NamespaceCode namespaceForPrefix(const QXmlNodeModelIndex &ni, const QXmlName::PrefixCode prefix) const
Returns the namespace URI on ni that corresponds to prefix.
QAtomicInt ref
Definition: qshareddata.h:59
double d
Definition: qnumeric_p.h:62
The QXmlNodeModelIndex class identifies a node in an XML node model subclassed from QAbstractXmlNodeM...
QIntegerForSizeof< void * >::Unsigned quintptr
Definition: qglobal.h:986
A push interface for the XPath Data Model. Similar to SAX&#39;s ContentHandler.
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
bool internalIsAtomicValue() const
bool isNull() const
Returns true if this QXmlNodeModelIndex is a default constructed value, otherwise false...
virtual void namespaceBinding(const QXmlName &nb)=0
Signals the presence of the namespace declaration nb.
static QVariant toQt(const AtomicValue *const value)
bool isNull() const
Returns true if this is a NULL variant, false otherwise.
Definition: qvariant.cpp:3102
#define it(className, varName)
qint16 NamespaceCode
Definition: qxmlname.h:82
Due to strong interdependencies, this file contains the definitions for the classes Item...
The QXmlItem class contains either an XML node or an atomic value.
virtual QXmlNodeModelIndex::NodeKind kind(const QXmlNodeModelIndex &ni) const =0
Returns a value indicating the kind of node identified by ni.
The QExplicitlySharedDataPointer class represents a pointer to an explicitly shared object...
Definition: qshareddata.h:136
The QList::const_iterator class provides an STL-style const iterator for QList and QQueue...
Definition: qlist.h:228
~QXmlItem()
Destructor.
#define Q_DISABLE_COPY(Class)
Disables the use of copy constructors and assignment operators for the given Class.
Definition: qglobal.h:2523
QAbstractXmlForwardIterator< T >::Ptr makeListIterator(const QList< T > &list)
const QPatternist::AtomicValue * m_atomicValue
virtual QPatternist::ItemIteratorPtr sequencedTypedValue(const QXmlNodeModelIndex &ni) const
uint qHash(const QXmlNodeModelIndex &index)
Computes a hash key from the QXmlNodeModelIndex index, and returns it.
bool ref()
Atomically increments the value of this QAtomicInt.
const AtomicValue * asAtomicValue() const
Definition: qitem_p.h:373
bool isNode() const
Determines whether this item is an atomic value, or a node.
Definition: qitem_p.h:349
QPatternist::NodeIndexStorage m_node
virtual QExplicitlySharedDataPointer< QAbstractXmlForwardIterator< QXmlNodeModelIndex > > iterate(const QXmlNodeModelIndex &ni, QXmlNodeModelIndex::Axis axis) const
Performs navigation, starting from ni, by returning an QAbstractXmlForwardIterator that returns nodes...
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
static const EmptyIterator< Item >::Ptr emptyIterator
QString prefix(const QXmlNamePool &query) const
Returns the prefix.
Definition: qxmlname.cpp:370
const QAbstractXmlNodeModel * model
virtual QXmlNodeModelIndex nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &origin) const =0
When QtXmlPatterns evaluate path expressions, it emulate them through a combination of calls with QSi...
QAbstractXmlForwardIterator< T >::Ptr makeVectorIterator(const QVector< T > &vector)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
QScopedPointer< QAbstractXmlNodeModelPrivate > d_ptr
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
qint64 data() const
Returns the first data value.
bool isNode() const
Returns true if this item is a Node.
The QAbstractXmlNodeModel class is an abstract base class for modeling non-XML data to look like XML ...
QAbstractXmlForwardIterator< QXmlNodeModelIndexIteratorPointer >::Ptr Ptr
bool operator==(const QXmlNodeModelIndex &other) const
Returns true if this node is the same as other.
bool deref()
Atomically decrements the value of this QAtomicInt.
QPatternist::NodeIndexStorage m_storage
The namespace for the internal API of QtXmlPatterns.
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
QXmlItem()
Constructs a null QXmlItem that is neither a node nor an atomic value.
The QSourceLocation class identifies a location in a resource by URI, line, and column.
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
QVariant toAtomicValue() const
If this QXmlItem represents an atomic value, it is converted to an appropriate QVariant and returned...
virtual QAbstractXmlForwardIterator< QXmlNodeModelIndexIteratorPointer >::Ptr copy() const
Copies this QAbstractXmlForwardIterator and returns the copy.
const QAbstractXmlNodeModel * model() const
Returns the QAbstractXmlNodeModel that this node index refers to.
virtual QPatternist::ItemTypePtr type(const QXmlNodeModelIndex &ni) const
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
QExplicitlySharedDataPointer< ItemType > ItemTypePtr
QXmlName name() const
Definition: qitem_p.h:446
virtual QVariant typedValue(const QXmlNodeModelIndex &n) const =0
Returns the typed value for node node.
NamespaceCode namespaceURI() const
Definition: qnamepool_p.h:503
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
Represents an item in the XPath 2.0 Data Model.
Definition: qitem_p.h:182
static const MergeIterator mergeIterator
NodeKind
Identifies a kind of node.
bool operator!=(const QXmlNodeModelIndex &other) const
Returns true if other is the same node as this.
bool isAtomicValue() const
Returns true if this item is an atomic value.
QExplicitlySharedDataPointer< QAbstractXmlForwardIterator< QXmlNodeModelIndex > > iterate(const Axis axis) const
Definition: qitem_p.h:456
virtual ~QAbstractXmlNodeModel()
Destructor.
static Item fromPublic(const QXmlItem &i)
Definition: qitem_p.h:408
QSourceLocation sourceLocation(const QXmlNodeModelIndex &index) const
Returns the source location for the object with the given index or a default constructed QSourceLocat...
virtual void sendNamespaces(const QXmlNodeModelIndex &n, QAbstractXmlReceiver *const receiver) const
Sends the namespaces declared on n to receiver.
QExplicitlySharedDataPointer< QAbstractXmlForwardIterator< QXmlNodeModelIndex > > mapToSequence(const QXmlNodeModelIndex &ni, const QExplicitlySharedDataPointer< QPatternist::DynamicContext > &) const
quint16 index
Axis
Identify the axes emanating from a node.
virtual bool isDeepEqual(const QXmlNodeModelIndex &ni1, const QXmlNodeModelIndex &ni2) const
Determines whether ni1 is deep equal to ni2.
QExplicitlySharedDataPointer< QAbstractXmlForwardIterator< QXmlNodeModelIndex > > QXmlNodeModelIndexIteratorPointer
QVector< QXmlNodeModelIndexIteratorPointer > ItVector
static bool isIgnorableInDeepEqual(const QXmlNodeModelIndex &n)
bool isEmpty() const
Returns true if the vector has size 0; otherwise returns false.
Definition: qvector.h:139
QXmlItem & operator=(const QXmlItem &other)
Assigns other to this.
The QFlags class provides a type-safe way of storing OR-combinations of enum values.
Definition: qglobal.h:2313
QXmlNodeModelIndex toNodeModelIndex() const
If this QXmlItem represents a node, it returns the item as a QXmlNodeModelIndex.
bool operator!=(const NodeIndexStorage &other) const
QAbstractXmlNodeModel()
Default constructor.
qint64 additionalData() const
Returns the second data value.
static const KeyPair *const end
virtual void copyNodeTo(const QXmlNodeModelIndex &node, QAbstractXmlReceiver *const receiver, const NodeCopySettings &) const
static Item toXDM(const QVariant &value)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
bool operator==(QBool b1, bool b2)
Definition: qglobal.h:2023
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
QString stringValue() const
Definition: qitem_p.h:509
NodeKind kind() const
Definition: qitem_p.h:471
Bridges values in Qt&#39;s QList container class into an QAbstractXmlForwardIterator. ...
virtual QVector< QXmlName > namespaceBindings(const QXmlNodeModelIndex &n) const =0
Returns the in-scope namespaces of n.
QExplicitlySharedDataPointer< QAbstractXmlNodeModel > Ptr
A QExplicitlySharedDataPointer {smart pointer} to an instance of QAbstractXmlNodeModel.
static bool isNull(const QVariant::Private *d)
Definition: qvariant.cpp:300
virtual QVector< QXmlNodeModelIndex > attributes(const QXmlNodeModelIndex &element) const =0
Returns the attributes of element.
static bool equal(const QChar *a, int l, const char *b)
Definition: qurl.cpp:3270
QXmlNodeModelIndexIteratorPointer mapToSequence(const QXmlNodeModelIndexIteratorPointer &it, const DynamicContext::Ptr &) const
bool isNull() const
Returns true if this QXmlItem is neither a node nor an atomic value.
The QList class is a template class that provides lists.
Definition: qdatastream.h:62
static QXmlNodeModelIndexIteratorPointer mergeIterators(const QXmlNodeModelIndex &node, const QXmlNodeModelIndexIteratorPointer &it2)
#define Q_FUNC_INFO
Definition: qglobal.h:1871
NamespaceCode PrefixCode
Definition: qxmlname.h:83