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
/*!
Returns the first child element with tag name \a tagName if tagName is non-empty;
otherwise returns the first child element. Returns a null element if no
such child exists.
Returns the first child element with tag name \a tagName and namespace URI
\a namespaceURI. If \a tagName is empty, returns the first child element
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()
*/
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()) {
if (child.isElement()) {
if (child.isElement() && (namespaceURI.isEmpty() || child.namespaceURI() == namespaceURI)) {
QDomElement elt = child.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName)
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;
otherwise returns the last child element. Returns a null element if no
such child exists.
Returns the last child element with tag name \a tagName and namespace URI
\a namespaceURI. If \a tagName is empty, returns the last child element
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()
*/
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()) {
if (child.isElement()) {
if (child.isElement() && (namespaceURI.isEmpty() || child.namespaceURI() == namespaceURI)) {
QDomElement elt = child.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName)
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
is non-empty; otherwise returns any next sibling element.
Returns a null element if no such sibling exists.
Returns the next sibling element with tag name \a tagName and namespace URI
\a namespaceURI. If \a tagName is empty, returns the next sibling element
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()
*/
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()) {
if (sib.isElement()) {
if (sib.isElement() && (namespaceURI.isEmpty() || sib.namespaceURI() == namespaceURI)) {
QDomElement elt = sib.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName)
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
is non-empty; otherwise returns any previous sibling element.
Returns a null element if no such sibling exists.
Returns the previous sibling element with tag name \a tagName and namespace
URI \a namespaceURI. If \a tagName is empty, returns the previous sibling
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()
*/
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()) {
if (sib.isElement()) {
if (sib.isElement() && (namespaceURI.isEmpty() || sib.namespaceURI() == namespaceURI)) {
QDomElement elt = sib.toElement();
if (tagName.isEmpty() || elt.tagName() == tagName)
return elt;

View File

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

View File

@ -1102,6 +1102,10 @@ void tst_QDom::browseElements()
root.appendChild(doc.createElement("bop"));
root.appendChild(doc.createElement("bar"));
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());
QDomElement foo = doc.firstChildElement("foo");
@ -1114,10 +1118,12 @@ void tst_QDom::browseElements()
QDomElement bar = foo.firstChildElement("bar");
QVERIFY(!bar.isNull());
QCOMPARE(bar.namespaceURI(), QString());
QVERIFY(bar.previousSiblingElement("bar").isNull());
QVERIFY(bar.previousSiblingElement().isNull());
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");
QVERIFY(!bop.isNull());
@ -1125,6 +1131,65 @@ void tst_QDom::browseElements()
QCOMPARE(bop.nextSiblingElement("bop"), foo.lastChildElement("bop"));
QCOMPARE(bop.previousSiblingElement("bar"), foo.firstChildElement("bar"));
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()