QDomNode: Add namespaceURI parameter to browse methods

This adds a namespaceURI parameter to the following methods of QDomNode:
firstChildElement(), lastChildElement(), nextChildElement() and
previousChildElement()

Those methods can now be used to filter for elements with a specific
namespaceURI without the need to use QDomNodeList.

[ChangeLog][QtXml][QDom] Added namespaceURI parameter to browse methods
like firstChildElement() to filter for elements with certain namespaces
without the need of QDomNodeList.

Change-Id: Ic2cfe8c6d5d5f6b5fcf27165df15bce54ad0f23a
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
Linus Jahn 2020-07-10 17:07:09 +02:00
parent 96e3ee0659
commit 51e3cd89a8
3 changed files with 100 additions and 25 deletions

View File

@ -2417,17 +2417,19 @@ bool QDomNode::isComment() const
#undef IMPL #undef IMPL
/*! /*!
Returns the first child element with tag name \a tagName if tagName is non-empty; Returns the first child element with tag name \a tagName and namespace URI
otherwise returns the first child element. Returns a null element if no \a namespaceURI. If \a tagName is empty, returns the first child element
such child exists. with \a namespaceURI, and if \a namespaceURI is empty, returns the first
child element with \a tagName. If the both parameters are empty, returns
the first child element. Returns a null element if no such child exists.
\sa lastChildElement(), previousSiblingElement(), nextSiblingElement() \sa lastChildElement(), previousSiblingElement(), nextSiblingElement()
*/ */
QDomElement QDomNode::firstChildElement(const QString &tagName) const QDomElement QDomNode::firstChildElement(const QString &tagName, const QString &namespaceURI) const
{ {
for (QDomNode child = firstChild(); !child.isNull(); child = child.nextSibling()) { for (QDomNode child = firstChild(); !child.isNull(); child = child.nextSibling()) {
if (child.isElement()) { if (child.isElement() && (namespaceURI.isEmpty() || child.namespaceURI() == namespaceURI)) {
QDomElement elt = child.toElement(); QDomElement elt = child.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName) if (tagName.isEmpty() || elt.tagName() == tagName)
return elt; return elt;
@ -2437,17 +2439,19 @@ QDomElement QDomNode::firstChildElement(const QString &tagName) const
} }
/*! /*!
Returns the last child element with tag name \a tagName if tagName is non-empty; Returns the last child element with tag name \a tagName and namespace URI
otherwise returns the last child element. Returns a null element if no \a namespaceURI. If \a tagName is empty, returns the last child element
such child exists. with \a namespaceURI, and if \a namespaceURI is empty, returns the last
child element with \a tagName. If the both parameters are empty, returns
the last child element. Returns a null element if no such child exists.
\sa firstChildElement(), previousSiblingElement(), nextSiblingElement() \sa firstChildElement(), previousSiblingElement(), nextSiblingElement()
*/ */
QDomElement QDomNode::lastChildElement(const QString &tagName) const QDomElement QDomNode::lastChildElement(const QString &tagName, const QString &namespaceURI) const
{ {
for (QDomNode child = lastChild(); !child.isNull(); child = child.previousSibling()) { for (QDomNode child = lastChild(); !child.isNull(); child = child.previousSibling()) {
if (child.isElement()) { if (child.isElement() && (namespaceURI.isEmpty() || child.namespaceURI() == namespaceURI)) {
QDomElement elt = child.toElement(); QDomElement elt = child.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName) if (tagName.isEmpty() || elt.tagName() == tagName)
return elt; return elt;
@ -2457,17 +2461,20 @@ QDomElement QDomNode::lastChildElement(const QString &tagName) const
} }
/*! /*!
Returns the next sibling element with tag name \a tagName if \a tagName Returns the next sibling element with tag name \a tagName and namespace URI
is non-empty; otherwise returns any next sibling element. \a namespaceURI. If \a tagName is empty, returns the next sibling element
Returns a null element if no such sibling exists. with \a namespaceURI, and if \a namespaceURI is empty, returns the next
sibling child element with \a tagName. If the both parameters are empty,
returns the next sibling element. Returns a null element if no such sibling
exists.
\sa firstChildElement(), previousSiblingElement(), lastChildElement() \sa firstChildElement(), previousSiblingElement(), lastChildElement()
*/ */
QDomElement QDomNode::nextSiblingElement(const QString &tagName) const QDomElement QDomNode::nextSiblingElement(const QString &tagName, const QString &namespaceURI) const
{ {
for (QDomNode sib = nextSibling(); !sib.isNull(); sib = sib.nextSibling()) { for (QDomNode sib = nextSibling(); !sib.isNull(); sib = sib.nextSibling()) {
if (sib.isElement()) { if (sib.isElement() && (namespaceURI.isEmpty() || sib.namespaceURI() == namespaceURI)) {
QDomElement elt = sib.toElement(); QDomElement elt = sib.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName) if (tagName.isEmpty() || elt.tagName() == tagName)
return elt; return elt;
@ -2477,17 +2484,20 @@ QDomElement QDomNode::nextSiblingElement(const QString &tagName) const
} }
/*! /*!
Returns the previous sibilng element with tag name \a tagName if \a tagName Returns the previous sibling element with tag name \a tagName and namespace
is non-empty; otherwise returns any previous sibling element. URI \a namespaceURI. If \a tagName is empty, returns the previous sibling
Returns a null element if no such sibling exists. element with \a namespaceURI, and if \a namespaceURI is empty, returns the
previous sibling element with \a tagName. If the both parameters are empty,
returns the previous sibling element. Returns a null element if no such
sibling exists.
\sa firstChildElement(), nextSiblingElement(), lastChildElement() \sa firstChildElement(), nextSiblingElement(), lastChildElement()
*/ */
QDomElement QDomNode::previousSiblingElement(const QString &tagName) const QDomElement QDomNode::previousSiblingElement(const QString &tagName, const QString &namespaceURI) const
{ {
for (QDomNode sib = previousSibling(); !sib.isNull(); sib = sib.previousSibling()) { for (QDomNode sib = previousSibling(); !sib.isNull(); sib = sib.previousSibling()) {
if (sib.isElement()) { if (sib.isElement() && (namespaceURI.isEmpty() || sib.namespaceURI() == namespaceURI)) {
QDomElement elt = sib.toElement(); QDomElement elt = sib.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName) if (tagName.isEmpty() || elt.tagName() == tagName)
return elt; return elt;

View File

@ -227,10 +227,10 @@ public:
void save(QTextStream&, int, EncodingPolicy=QDomNode::EncodingFromDocument) const; void save(QTextStream&, int, EncodingPolicy=QDomNode::EncodingFromDocument) const;
QDomElement firstChildElement(const QString &tagName = QString()) const; QDomElement firstChildElement(const QString &tagName = QString(), const QString &namespaceURI = QString()) const;
QDomElement lastChildElement(const QString &tagName = QString()) const; QDomElement lastChildElement(const QString &tagName = QString(), const QString &namespaceURI = QString()) const;
QDomElement previousSiblingElement(const QString &tagName = QString()) const; QDomElement previousSiblingElement(const QString &tagName = QString(), const QString &namespaceURI = QString()) const;
QDomElement nextSiblingElement(const QString &taName = QString()) const; QDomElement nextSiblingElement(const QString &taName = QString(), const QString &namespaceURI = QString()) const;
int lineNumber() const; int lineNumber() const;
int columnNumber() const; int columnNumber() const;

View File

@ -1102,6 +1102,10 @@ void tst_QDom::browseElements()
root.appendChild(doc.createElement("bop")); root.appendChild(doc.createElement("bop"));
root.appendChild(doc.createElement("bar")); root.appendChild(doc.createElement("bar"));
root.appendChild(doc.createElement("bop")); root.appendChild(doc.createElement("bop"));
root.appendChild(doc.createElementNS("org.example.bar", "bar"));
root.appendChild(doc.createElementNS("org.example.foo", "flup"));
root.appendChild(doc.createElementNS("org.example.foo2", "flup"));
root.appendChild(doc.createElementNS("org.example.bar", "bar2"));
QVERIFY(doc.firstChildElement("ding").isNull()); QVERIFY(doc.firstChildElement("ding").isNull());
QDomElement foo = doc.firstChildElement("foo"); QDomElement foo = doc.firstChildElement("foo");
@ -1114,10 +1118,12 @@ void tst_QDom::browseElements()
QDomElement bar = foo.firstChildElement("bar"); QDomElement bar = foo.firstChildElement("bar");
QVERIFY(!bar.isNull()); QVERIFY(!bar.isNull());
QCOMPARE(bar.namespaceURI(), QString());
QVERIFY(bar.previousSiblingElement("bar").isNull()); QVERIFY(bar.previousSiblingElement("bar").isNull());
QVERIFY(bar.previousSiblingElement().isNull()); QVERIFY(bar.previousSiblingElement().isNull());
QCOMPARE(bar.nextSiblingElement("bar").tagName(), QLatin1String("bar")); QCOMPARE(bar.nextSiblingElement("bar").tagName(), QLatin1String("bar"));
QVERIFY(bar.nextSiblingElement("bar").nextSiblingElement("bar").isNull()); QCOMPARE(bar.nextSiblingElement("bar").nextSiblingElement("bar").tagName(), QLatin1String("bar"));
QVERIFY(bar.nextSiblingElement("bar").nextSiblingElement("bar").nextSiblingElement("bar").isNull());
QDomElement bop = foo.firstChildElement("bop"); QDomElement bop = foo.firstChildElement("bop");
QVERIFY(!bop.isNull()); QVERIFY(!bop.isNull());
@ -1125,6 +1131,65 @@ void tst_QDom::browseElements()
QCOMPARE(bop.nextSiblingElement("bop"), foo.lastChildElement("bop")); QCOMPARE(bop.nextSiblingElement("bop"), foo.lastChildElement("bop"));
QCOMPARE(bop.previousSiblingElement("bar"), foo.firstChildElement("bar")); QCOMPARE(bop.previousSiblingElement("bar"), foo.firstChildElement("bar"));
QCOMPARE(bop.previousSiblingElement("bar"), foo.firstChildElement()); QCOMPARE(bop.previousSiblingElement("bar"), foo.firstChildElement());
bar = foo.firstChildElement("bar", "org.example.bar");
QVERIFY(!bar.isNull());
QCOMPARE(bar.tagName(), QLatin1String("bar"));
QCOMPARE(bar.namespaceURI(), QLatin1String("org.example.bar"));
QVERIFY(bar.nextSiblingElement("bar", "org.example.bar").isNull());
QVERIFY(bar.nextSiblingElement("bar").isNull());
QVERIFY(bar.previousSiblingElement("bar", "org.example.bar").isNull());
QVERIFY(!bar.previousSiblingElement("bar").isNull());
bar = foo.firstChildElement("bar", "");
QCOMPARE(bar.namespaceURI(), QString());
bar = foo.lastChildElement("bar");
QCOMPARE(bar.namespaceURI(), QLatin1String("org.example.bar"));
bar = foo.lastChildElement("bar", "");
QCOMPARE(bar.namespaceURI(), QLatin1String("org.example.bar"));
QVERIFY(foo.firstChildElement("bar", "abc").isNull());
QVERIFY(foo.lastChildElement("bar", "abc").isNull());
QDomElement barNS = foo.firstChildElement(QString(), "org.example.bar");
QVERIFY(!barNS.isNull());
QCOMPARE(barNS.tagName(), "bar");
QVERIFY(!barNS.nextSiblingElement(QString(), "org.example.bar").isNull());
QVERIFY(barNS.previousSiblingElement(QString(), "org.example.bar").isNull());
barNS = foo.firstChildElement("", "org.example.bar");
QVERIFY(!barNS.isNull());
QCOMPARE(barNS.tagName(), "bar");
QVERIFY(!barNS.nextSiblingElement("", "org.example.bar").isNull());
QVERIFY(barNS.previousSiblingElement("", "org.example.bar").isNull());
barNS = foo.lastChildElement(QString(), "org.example.bar");
QVERIFY(!barNS.isNull());
QCOMPARE(barNS.tagName(), "bar2");
QVERIFY(barNS.nextSiblingElement(QString(), "org.example.bar").isNull());
QVERIFY(!barNS.previousSiblingElement(QString(), "org.example.bar").isNull());
barNS = foo.lastChildElement("", "org.example.bar");
QVERIFY(!barNS.isNull());
QCOMPARE(barNS.tagName(), "bar2");
QVERIFY(barNS.nextSiblingElement("", "org.example.bar").isNull());
QVERIFY(!barNS.previousSiblingElement("", "org.example.bar").isNull());
QDomElement flup = foo.firstChildElement("flup");
QVERIFY(!flup.isNull());
QCOMPARE(flup.namespaceURI(), QLatin1String("org.example.foo"));
QVERIFY(flup.previousSiblingElement("flup").isNull());
QVERIFY(!flup.nextSiblingElement("flup").isNull());
QVERIFY(flup.previousSiblingElement("flup", "org.example.foo").isNull());
QVERIFY(flup.nextSiblingElement("flup", "org.example.foo").isNull());
QVERIFY(flup.previousSiblingElement("flup", "org.example.foo2").isNull());
QVERIFY(!flup.nextSiblingElement("flup", "org.example.foo2").isNull());
QDomElement flup2 = flup.nextSiblingElement("flup");
QCOMPARE(flup2.namespaceURI(), QLatin1String("org.example.foo2"));
flup2 = foo.firstChildElement("flup", "org.example.foo2");
QCOMPARE(flup2.namespaceURI(), QLatin1String("org.example.foo2"));
} }
void tst_QDom::domNodeMapAndList() void tst_QDom::domNodeMapAndList()