diff options
-rw-r--r-- | src/corelib/xml/qxmlstream.cpp | 58 | ||||
-rw-r--r-- | src/corelib/xml/qxmlstream.h | 7 | ||||
-rw-r--r-- | tests/auto/qxmlstream/tst_qxmlstream.cpp | 51 |
3 files changed, 108 insertions, 8 deletions
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 8b2462e..a311b99 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -129,6 +129,21 @@ QT_BEGIN_NAMESPACE */ /*! + \enum QXmlStreamReader::ReadElementTextBehaviour + + This enum specifies the different behaviours of readElementText(). + + \value ErrorOnUnexpectedElement Raise an UnexpectedElementError and return + what was read so far when a child element is encountered. + + \value IncludeChildElements Recursively include the text from child elements. + + \value SkipChildElements Skip child elements. + + \since 4.6 +*/ + +/*! \enum QXmlStreamReader::Error This enum specifies different error cases @@ -637,6 +652,7 @@ QXmlStreamReader::TokenType QXmlStreamReader::tokenType() const this function. \since 4.6 + \sa readNext() */ bool QXmlStreamReader::readNextStartElement() { @@ -2070,12 +2086,17 @@ void QXmlStreamReader::addExtraNamespaceDeclarations(const QXmlStreamNamespaceDe The function concatenates text() when it reads either \l Characters or EntityReference tokens, but skips ProcessingInstruction and \l - Comment. In case anything else is read before reaching EndElement, - the function returns what it read so far and raises an - UnexpectedElementError. If the current token is not StartElement, an - empty string is returned. + Comment. If the current token is not StartElement, an empty string is + returned. + + The \a behaviour defines what happens in case anything else is + read before reaching EndElement. The function can include the text from + child elements (useful for example for HTML), ignore child elements, or + raise an UnexpectedElementError and return what was read so far. + + \since 4.6 */ -QString QXmlStreamReader::readElementText() +QString QXmlStreamReader::readElementText(ReadElementTextBehaviour behaviour) { Q_D(QXmlStreamReader); if (isStartElement()) { @@ -2091,16 +2112,37 @@ QString QXmlStreamReader::readElementText() case ProcessingInstruction: case Comment: break; + case StartElement: + if (behaviour == SkipChildElements) { + skipCurrentElement(); + break; + } else if (behaviour == IncludeChildElements) { + result += readElementText(behaviour); + break; + } + // Fall through (for ErrorOnUnexpectedElement) default: - if (!d->error) - d->raiseError(UnexpectedElementError, QXmlStream::tr("Expected character data.")); - return result; + if (d->error || behaviour == ErrorOnUnexpectedElement) { + if (!d->error) + d->raiseError(UnexpectedElementError, QXmlStream::tr("Expected character data.")); + return result; + } } } } return QString(); } +/*! + \overload readElementText() + + Calling this function is equivalent to calling readElementText(ErrorOnUnexpectedElement). + */ +QString QXmlStreamReader::readElementText() +{ + return readElementText(ErrorOnUnexpectedElement); +} + /*! Raises a custom error with an optional error \a message. \sa error(), errorString() diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h index 21dcb40..71deb66 100644 --- a/src/corelib/xml/qxmlstream.h +++ b/src/corelib/xml/qxmlstream.h @@ -351,6 +351,13 @@ public: qint64 characterOffset() const; QXmlStreamAttributes attributes() const; + + enum ReadElementTextBehaviour { + ErrorOnUnexpectedElement, + IncludeChildElements, + SkipChildElements + }; + QString readElementText(ReadElementTextBehaviour behaviour); QString readElementText(); QStringRef name() const; diff --git a/tests/auto/qxmlstream/tst_qxmlstream.cpp b/tests/auto/qxmlstream/tst_qxmlstream.cpp index f496dcf..04f990f 100644 --- a/tests/auto/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/qxmlstream/tst_qxmlstream.cpp @@ -55,6 +55,8 @@ //TESTED_CLASS=QXmlStreamReader QXmlStreamWriter //TESTED_FILES=corelib/xml/stream/qxmlutils.cpp corelib/xml/stream/qxmlstream.cpp corelib/xml/stream/qxmlstream_p.h +Q_DECLARE_METATYPE(QXmlStreamReader::ReadElementTextBehaviour) + static const char *const catalogFile = "XML-Test-Suite/xmlconf/finalCatalog.xml"; static const int expectedRunCount = 1646; static const int expectedSkipCount = 532; @@ -551,6 +553,8 @@ private slots: void readFromQBuffer() const; void readFromQBufferInvalid() const; void readNextStartElement() const; + void readElementText() const; + void readElementText_data() const; void crashInUTF16Codec() const; void hasAttributeSignature() const; void hasAttribute() const; @@ -1126,6 +1130,53 @@ void tst_QXmlStream::readNextStartElement() const QCOMPARE(amountOfB, 2); } +void tst_QXmlStream::readElementText() const +{ + QFETCH(QXmlStreamReader::ReadElementTextBehaviour, behaviour); + QFETCH(QString, input); + QFETCH(QString, expected); + + QXmlStreamReader reader(input); + + QVERIFY(reader.readNextStartElement()); + QCOMPARE(reader.readElementText(behaviour), expected); +} + +void tst_QXmlStream::readElementText_data() const +{ + QTest::addColumn<QXmlStreamReader::ReadElementTextBehaviour>("behaviour"); + QTest::addColumn<QString>("input"); + QTest::addColumn<QString>("expected"); + + QString validInput("<p>He was <em>never</em> going to admit<!-- TODO: rephrase --> his mistake.</p>"); + QString invalidInput("<p>invalid...<p>"); + QString invalidOutput("invalid..."); + + QTest::newRow("ErrorOnUnexpectedElement") + << QXmlStreamReader::ErrorOnUnexpectedElement + << validInput << QString("He was "); + + QTest::newRow("IncludeChildElements") + << QXmlStreamReader::IncludeChildElements + << validInput << QString("He was never going to admit his mistake."); + + QTest::newRow("SkipChildElements") + << QXmlStreamReader::SkipChildElements + << validInput << QString("He was going to admit his mistake."); + + QTest::newRow("ErrorOnUnexpectedElement Invalid") + << QXmlStreamReader::ErrorOnUnexpectedElement + << invalidInput << invalidOutput; + + QTest::newRow("IncludeChildElements Invalid") + << QXmlStreamReader::IncludeChildElements + << invalidInput << invalidOutput; + + QTest::newRow("SkipChildElements Invalid") + << QXmlStreamReader::SkipChildElements + << invalidInput << invalidOutput; +} + void tst_QXmlStream::crashInUTF16Codec() const { QEventLoop eventLoop; |