Improve QDomDocument::setContent() API
Added new setContent() overloads, that: - take parameter of new ParseOptions enum type for specifying the parse options that can be used for enabling namepsace processing and, in future, whitespace-only text nodes, etc. - use ParseResult for returning the information about error message, line and coulmn number, instead of three parameters for each. - use QAnyStringView for a QString input data. To avoid ambiguities when calling setContent() with one argument, removed the default argument for errorString from all the overloads. [ChangeLog][QtXml][QDomDocument] Added new setContent() overloads that allow specifying different parse options through ParseOptions flags. These overloads use a new ParseResult struct for returning the information about an error, and QAnyStringView for passing string input. [ChangeLog][QtXml][QDomDocument][Potentially Source-Incompatible Changes] setContent() overloads that take only one argument now return ParseResult instead of a bool. ParseResult explicitly converts to bool, so the expressions calling setContent() with one argument will continue compiling, if they are contextually convertible to bool. If an implicit convertion is required (e.g. bool b = doc.setConetnt(data)), the result needs to be explicitly converted to bool first (e.g. bool b = bool(doc.setConetnt(data)). Task-number: QTBUG-104507 Change-Id: If6a78f8c9b1458f0e3ae719bfd3703a0b965449c Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
b65e37b744
commit
8cc389068b
@ -5609,8 +5609,8 @@ void QDomDocumentPrivate::clear()
|
||||
QDomNodePrivate::clear();
|
||||
}
|
||||
|
||||
bool QDomDocumentPrivate::setContent(QXmlStreamReader *reader, bool namespaceProcessing,
|
||||
QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
QDomDocument::ParseResult QDomDocumentPrivate::setContent(QXmlStreamReader *reader,
|
||||
QDomDocument::ParseOptions options)
|
||||
{
|
||||
clear();
|
||||
impl = new QDomImplementationPrivate;
|
||||
@ -5618,23 +5618,18 @@ bool QDomDocumentPrivate::setContent(QXmlStreamReader *reader, bool namespacePro
|
||||
type->ref.deref();
|
||||
|
||||
if (!reader) {
|
||||
qWarning("Failed to set content, XML reader is not initialized");
|
||||
return false;
|
||||
const auto error = u"Failed to set content, XML reader is not initialized"_s;
|
||||
qWarning("%s", qPrintable(error));
|
||||
return { error };
|
||||
}
|
||||
|
||||
QDomParser domParser(this, reader, namespaceProcessing);
|
||||
QDomParser domParser(this, reader, options);
|
||||
|
||||
if (!domParser.parse()) {
|
||||
if (errorMsg)
|
||||
*errorMsg = std::get<0>(domParser.errorInfo());
|
||||
if (errorLine)
|
||||
*errorLine = std::get<1>(domParser.errorInfo());
|
||||
if (errorColumn)
|
||||
*errorColumn = std::get<2>(domParser.errorInfo());
|
||||
return false;
|
||||
const auto info = domParser.errorInfo();
|
||||
return { std::get<0>(info), std::get<1>(info), std::get<2>(info) };
|
||||
}
|
||||
|
||||
return true;
|
||||
return {};
|
||||
}
|
||||
|
||||
QDomNodePrivate* QDomDocumentPrivate::cloneNode(bool deep)
|
||||
@ -6046,14 +6041,12 @@ QDomDocument::~QDomDocument()
|
||||
Since \a text is already a Unicode string, no encoding detection
|
||||
is done.
|
||||
*/
|
||||
bool QDomDocument::setContent(const QString& text, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
bool QDomDocument::setContent(const QString& text, bool namespaceProcessing,
|
||||
QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
{
|
||||
if (!impl)
|
||||
impl = new QDomDocumentPrivate();
|
||||
|
||||
QXmlStreamReader streamReader(text);
|
||||
streamReader.setNamespaceProcessing(namespaceProcessing);
|
||||
return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn);
|
||||
QXmlStreamReader reader(text);
|
||||
reader.setNamespaceProcessing(namespaceProcessing);
|
||||
return setContent(&reader, namespaceProcessing, errorMsg, errorLine, errorColumn);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -6085,6 +6078,7 @@ bool QDomDocument::setContent(const QString& text, bool namespaceProcessing, QSt
|
||||
QDomNode::prefix(), QDomNode::localName() and
|
||||
QDomNode::namespaceURI() return an empty string.
|
||||
|
||||
//! [entity-refs]
|
||||
Entity references are handled as follows:
|
||||
\list
|
||||
\li References to internal general entities and character entities occurring in the
|
||||
@ -6099,18 +6093,36 @@ bool QDomDocument::setContent(const QString& text, bool namespaceProcessing, QSt
|
||||
occurs outside of the content is replaced with an empty string.
|
||||
\li Any unparsed entity reference is replaced with an empty string.
|
||||
\endlist
|
||||
//! [entity-refs]
|
||||
|
||||
\sa QDomNode::namespaceURI(), QDomNode::localName(),
|
||||
QDomNode::prefix(), QString::isNull(), QString::isEmpty()
|
||||
*/
|
||||
bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing,
|
||||
QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
{
|
||||
if (!impl)
|
||||
impl = new QDomDocumentPrivate();
|
||||
QXmlStreamReader reader(data);
|
||||
reader.setNamespaceProcessing(namespaceProcessing);
|
||||
return setContent(&reader, namespaceProcessing, errorMsg, errorLine, errorColumn);
|
||||
}
|
||||
|
||||
QXmlStreamReader streamReader(data);
|
||||
streamReader.setNamespaceProcessing(namespaceProcessing);
|
||||
return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn);
|
||||
static inline QDomDocument::ParseOptions toParseOptions(bool namespaceProcessing)
|
||||
{
|
||||
return namespaceProcessing ? QDomDocument::ParseOption::UseNamespaceProcessing
|
||||
: QDomDocument::ParseOption::Default;
|
||||
}
|
||||
|
||||
static inline void unpackParseResult(const QDomDocument::ParseResult &parseResult,
|
||||
QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
{
|
||||
if (!parseResult) {
|
||||
if (errorMsg)
|
||||
*errorMsg = parseResult.errorMessage;
|
||||
if (errorLine)
|
||||
*errorLine = static_cast<int>(parseResult.errorLine);
|
||||
if (errorColumn)
|
||||
*errorColumn = static_cast<int>(parseResult.errorLine);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -6124,25 +6136,12 @@ bool QDomDocument::setContent(const QByteArray &data, bool namespaceProcessing,
|
||||
This will change in Qt 7, which will no longer open \a dev. Applications
|
||||
should therefore open the device themselves before calling setContent.
|
||||
*/
|
||||
bool QDomDocument::setContent(QIODevice* dev, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
bool QDomDocument::setContent(QIODevice* dev, bool namespaceProcessing,
|
||||
QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
{
|
||||
if (!impl)
|
||||
impl = new QDomDocumentPrivate();
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
|
||||
if (!dev->isOpen()) {
|
||||
qWarning("QDomDocument called with unopened QIODevice. "
|
||||
"This will not be supported in future Qt versions.");
|
||||
if (!dev->open(QIODevice::ReadOnly)) {
|
||||
qWarning("QDomDocument::setContent: Failed to open device.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QXmlStreamReader streamReader(dev);
|
||||
streamReader.setNamespaceProcessing(namespaceProcessing);
|
||||
return IMPL->setContent(&streamReader, namespaceProcessing, errorMsg, errorLine, errorColumn);
|
||||
ParseResult result = setContent(dev, toParseOptions(namespaceProcessing));
|
||||
unpackParseResult(result, errorMsg, errorLine, errorColumn);
|
||||
return bool(result);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -6207,12 +6206,159 @@ bool QDomDocument::setContent(QIODevice* dev, QString *errorMsg, int *errorLine,
|
||||
|
||||
\sa QXmlStreamReader
|
||||
*/
|
||||
bool QDomDocument::setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg,
|
||||
int *errorLine, int *errorColumn)
|
||||
bool QDomDocument::setContent(QXmlStreamReader *reader, bool namespaceProcessing,
|
||||
QString *errorMsg, int *errorLine, int *errorColumn)
|
||||
{
|
||||
ParseResult result = setContent(reader, toParseOptions(namespaceProcessing));
|
||||
unpackParseResult(result, errorMsg, errorLine, errorColumn);
|
||||
return bool(result);
|
||||
}
|
||||
|
||||
/*!
|
||||
\enum QDomDocument::ParseOption
|
||||
\since 6.5
|
||||
|
||||
This enum describes the possible options that can be used when
|
||||
parsing an XML document using the setContent() method.
|
||||
|
||||
\value Default No parse options are set.
|
||||
\value UseNamespaceProcessing Namespace processing is enabled.
|
||||
|
||||
\sa setContent()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDomDocument::ParseResult
|
||||
\since 6.5
|
||||
\inmodule QtXml
|
||||
\ingroup xml-tools
|
||||
\brief The struct is used to store the result of QDomDocument::setContent().
|
||||
|
||||
The QDomDocument::ParseResult struct is used for storing the result of
|
||||
QDomDocument::setContent(). If an error is found while parsing an XML
|
||||
document, the message, line and column number of an error are stored in
|
||||
\c ParseResult.
|
||||
|
||||
\sa QDomDocument::setContent()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\variable QDomDocument::ParseResult::errorMessage
|
||||
|
||||
The field contains the text message of an error found by
|
||||
QDomDocument::setContent() while parsing an XML document.
|
||||
|
||||
\sa QDomDocument::setContent()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\variable QDomDocument::ParseResult::errorLine
|
||||
|
||||
The field contains the line number of an error found by
|
||||
QDomDocument::setContent() while parsing an XML document.
|
||||
|
||||
\sa QDomDocument::setContent()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\variable QDomDocument::ParseResult::errorColumn
|
||||
|
||||
The field contains the column number of an error found by
|
||||
QDomDocument::setContent() while parsing an XML document.
|
||||
|
||||
\sa QDomDocument::setContent()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDomDocument::ParseResult::operator bool() const
|
||||
|
||||
Returns \c true if an error is found by QDomDocument::setContent();
|
||||
otherwise returns \c false.
|
||||
|
||||
\sa QDomDocument::setContent()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn ParseResult QDomDocument::setContent(const QByteArray &data, ParseOptions options)
|
||||
\fn ParseResult QDomDocument::setContent(QAnyStringView text, ParseOptions options)
|
||||
\fn ParseResult QDomDocument::setContent(QIODevice *device, ParseOptions options)
|
||||
\fn ParseResult QDomDocument::setContent(QXmlStreamReader *reader, ParseOptions options)
|
||||
|
||||
\since 6.5
|
||||
|
||||
This function parses the XML document from the byte array \a
|
||||
data, string view \a text, IO \a device, or stream \a reader
|
||||
and sets it as the content of the document. It tries to
|
||||
detect the encoding of the document, in accordance with the
|
||||
XML specification. Returns the result of parsing in ParseResult,
|
||||
which explicitly converts to \c bool.
|
||||
|
||||
You can use the \a options parameter to specify different parsing
|
||||
options, for example, to enable namespace processing, etc.
|
||||
|
||||
By default, namespace processing is disabled. If it's disabled, the
|
||||
parser does no namespace processing when it reads the XML file. The
|
||||
functions QDomNode::prefix(), QDomNode::localName() and
|
||||
QDomNode::namespaceURI() return an empty string.
|
||||
|
||||
If namespace processing is enabled via the parse \a options, the parser
|
||||
recognizes namespaces in the XML file and sets the prefix name, local
|
||||
name and namespace URI to appropriate values. The functions
|
||||
QDomNode::prefix(), QDomNode::localName() and QDomNode::namespaceURI()
|
||||
return a string for all elements and attributes and return an empty
|
||||
string if the element or attribute has no prefix.
|
||||
|
||||
Text nodes consisting only of whitespace are stripped and won't
|
||||
appear in the QDomDocument.
|
||||
|
||||
\include qdom.cpp entity-refs
|
||||
|
||||
\note The overload taking IO \a device will try to open it in read-only
|
||||
mode if it is not already open. In that case, the caller is responsible
|
||||
for calling close. This will change in Qt 7, which will no longer open
|
||||
the IO \a device. Applications should therefore open the device themselves
|
||||
before calling setContent().
|
||||
|
||||
\sa ParseResult, ParseOptions
|
||||
*/
|
||||
QDomDocument::ParseResult QDomDocument::setContentImpl(const QByteArray &data, ParseOptions options)
|
||||
{
|
||||
QXmlStreamReader reader(data);
|
||||
reader.setNamespaceProcessing(options.testFlag(ParseOption::UseNamespaceProcessing));
|
||||
return setContent(&reader, options);
|
||||
}
|
||||
|
||||
QDomDocument::ParseResult QDomDocument::setContent(QAnyStringView data, ParseOptions options)
|
||||
{
|
||||
QXmlStreamReader reader(data);
|
||||
reader.setNamespaceProcessing(options.testFlag(ParseOption::UseNamespaceProcessing));
|
||||
return setContent(&reader, options);
|
||||
}
|
||||
|
||||
QDomDocument::ParseResult QDomDocument::setContent(QIODevice *device, ParseOptions options)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
|
||||
if (!device->isOpen()) {
|
||||
qWarning("QDomDocument called with unopened QIODevice. "
|
||||
"This will not be supported in future Qt versions.");
|
||||
if (!device->open(QIODevice::ReadOnly)) {
|
||||
const auto error = u"QDomDocument::setContent: Failed to open device."_s;
|
||||
qWarning("%s", qPrintable(error));
|
||||
return { error };
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
QXmlStreamReader reader(device);
|
||||
reader.setNamespaceProcessing(options.testFlag(ParseOption::UseNamespaceProcessing));
|
||||
return setContent(&reader, options);
|
||||
}
|
||||
|
||||
QDomDocument::ParseResult QDomDocument::setContent(QXmlStreamReader *reader, ParseOptions options)
|
||||
{
|
||||
if (!impl)
|
||||
impl = new QDomDocumentPrivate();
|
||||
return IMPL->setContent(reader, namespaceProcessing, errorMsg, errorLine, errorColumn);
|
||||
return IMPL->setContent(reader, options);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -265,6 +265,21 @@ private:
|
||||
class Q_XML_EXPORT QDomDocument : public QDomNode
|
||||
{
|
||||
public:
|
||||
enum class ParseOption {
|
||||
Default = 0x00,
|
||||
UseNamespaceProcessing = 0x01,
|
||||
};
|
||||
Q_DECLARE_FLAGS(ParseOptions, ParseOption)
|
||||
|
||||
struct ParseResult
|
||||
{
|
||||
QString errorMessage;
|
||||
qsizetype errorLine = 0;
|
||||
qsizetype errorColumn = 0;
|
||||
|
||||
explicit operator bool() const noexcept { return errorMessage.isEmpty(); }
|
||||
};
|
||||
|
||||
QDomDocument();
|
||||
explicit QDomDocument(const QString& name);
|
||||
explicit QDomDocument(const QDomDocumentType& doctype);
|
||||
@ -300,17 +315,26 @@ public:
|
||||
bool setContent(const QByteArray &text, bool namespaceProcessing, QString *errorMsg = nullptr, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(const QString &text, bool namespaceProcessing, QString *errorMsg = nullptr, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(QIODevice *dev, bool namespaceProcessing, QString *errorMsg = nullptr, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(const QByteArray &text, QString *errorMsg = nullptr, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(const QString &text, QString *errorMsg = nullptr, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(QIODevice *dev, QString *errorMsg = nullptr, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(const QByteArray &text, QString *errorMsg, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(const QString &text, QString *errorMsg, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(QIODevice *dev, QString *errorMsg, int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
bool setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg = nullptr,
|
||||
int *errorLine = nullptr, int *errorColumn = nullptr);
|
||||
|
||||
Q_WEAK_OVERLOAD
|
||||
ParseResult setContent(const QByteArray &data, ParseOptions options = ParseOption::Default)
|
||||
{ return setContentImpl(data, options); }
|
||||
ParseResult setContent(QAnyStringView data, ParseOptions options = ParseOption::Default);
|
||||
ParseResult setContent(QIODevice *device, ParseOptions options = ParseOption::Default);
|
||||
ParseResult setContent(QXmlStreamReader *reader, ParseOptions options = ParseOption::Default);
|
||||
|
||||
// Qt extensions
|
||||
QString toString(int = 1) const;
|
||||
QByteArray toByteArray(int = 1) const;
|
||||
|
||||
private:
|
||||
ParseResult setContentImpl(const QByteArray &data, ParseOptions options);
|
||||
|
||||
QDomDocument(QDomDocumentPrivate*);
|
||||
|
||||
friend class QDomNode;
|
||||
|
@ -425,8 +425,8 @@ public:
|
||||
QDomDocumentPrivate(QDomDocumentPrivate *n, bool deep);
|
||||
~QDomDocumentPrivate();
|
||||
|
||||
bool setContent(QXmlStreamReader *reader, bool namespaceProcessing, QString *errorMsg,
|
||||
int *errorLine, int *errorColumn);
|
||||
QDomDocument::ParseResult setContent(QXmlStreamReader *reader,
|
||||
QDomDocument::ParseOptions options);
|
||||
|
||||
// Attributes
|
||||
QDomDocumentTypePrivate *doctype() { return type.data(); }
|
||||
|
@ -22,13 +22,9 @@ using namespace Qt::StringLiterals;
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
QDomBuilder::QDomBuilder(QDomDocumentPrivate *d, QXmlStreamReader *r, bool namespaceProcessing)
|
||||
: errorLine(0),
|
||||
errorColumn(0),
|
||||
doc(d),
|
||||
node(d),
|
||||
reader(r),
|
||||
nsProcessing(namespaceProcessing)
|
||||
QDomBuilder::QDomBuilder(QDomDocumentPrivate *d, QXmlStreamReader *r,
|
||||
QDomDocument::ParseOptions options)
|
||||
: errorLine(0), errorColumn(0), doc(d), node(d), reader(r), parseOptions(options)
|
||||
{
|
||||
Q_ASSERT(doc);
|
||||
Q_ASSERT(reader);
|
||||
@ -84,6 +80,8 @@ bool QDomBuilder::parseDTD(const QString &dtd)
|
||||
bool QDomBuilder::startElement(const QString &nsURI, const QString &qName,
|
||||
const QXmlStreamAttributes &atts)
|
||||
{
|
||||
const bool nsProcessing =
|
||||
parseOptions.testFlag(QDomDocument::ParseOption::UseNamespaceProcessing);
|
||||
QDomNodePrivate *n =
|
||||
nsProcessing ? doc->createElementNS(nsURI, qName) : doc->createElement(qName);
|
||||
if (!n)
|
||||
@ -232,8 +230,9 @@ bool QDomBuilder::notationDecl(const QString &name, const QString &publicId,
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
QDomParser::QDomParser(QDomDocumentPrivate *d, QXmlStreamReader *r, bool namespaceProcessing)
|
||||
: reader(r), domBuilder(d, r, namespaceProcessing)
|
||||
QDomParser::QDomParser(QDomDocumentPrivate *d, QXmlStreamReader *r,
|
||||
QDomDocument::ParseOptions options)
|
||||
: reader(r), domBuilder(d, r, options)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#define QDOMHELPERS_P_H
|
||||
|
||||
#include <qcoreapplication.h>
|
||||
#include <qdom.h>
|
||||
#include <private/qglobal_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -33,7 +34,7 @@ class QXmlStreamAttributes;
|
||||
class QDomBuilder
|
||||
{
|
||||
public:
|
||||
QDomBuilder(QDomDocumentPrivate *d, QXmlStreamReader *r, bool namespaceProcessing);
|
||||
QDomBuilder(QDomDocumentPrivate *d, QXmlStreamReader *r, QDomDocument::ParseOptions options);
|
||||
~QDomBuilder();
|
||||
|
||||
bool endDocument();
|
||||
@ -68,7 +69,7 @@ private:
|
||||
QDomNodePrivate *node;
|
||||
QXmlStreamReader *reader;
|
||||
QString entityName;
|
||||
bool nsProcessing;
|
||||
QDomDocument::ParseOptions parseOptions;
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
@ -81,7 +82,7 @@ class QDomParser
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(QDomParser)
|
||||
public:
|
||||
QDomParser(QDomDocumentPrivate *d, QXmlStreamReader *r, bool namespaceProcessing);
|
||||
QDomParser(QDomDocumentPrivate *d, QXmlStreamReader *r, QDomDocument::ParseOptions options);
|
||||
|
||||
bool parse();
|
||||
QDomBuilder::ErrorInfo errorInfo() const;
|
||||
|
@ -30,6 +30,9 @@ private slots:
|
||||
void namespacedAttributes() const;
|
||||
void setContent_data();
|
||||
void setContent();
|
||||
void setContentOverloads();
|
||||
void parseOptions();
|
||||
void parseResult();
|
||||
void toString_01_data();
|
||||
void toString_01();
|
||||
void toString_02_data();
|
||||
@ -187,6 +190,126 @@ void tst_QDom::setContent()
|
||||
QVERIFY( domDoc1.setContent( doc ) );
|
||||
QVERIFY( domDoc2.setContent( eRes ) );
|
||||
QVERIFY( compareDocuments( domDoc1, domDoc2 ) );
|
||||
|
||||
// Test overload taking a QAnyStringView
|
||||
QDomDocument domFromStringView;
|
||||
QStringView stringView(doc);
|
||||
QVERIFY(domFromStringView.setContent(stringView));
|
||||
QVERIFY(compareDocuments(domFromStringView, domDoc));
|
||||
|
||||
// Test overload taking a QByteArray
|
||||
QDomDocument domFromByteArary;
|
||||
QByteArray byteArray = doc.toUtf8();
|
||||
QVERIFY(domFromByteArary.setContent(byteArray));
|
||||
QVERIFY(compareDocuments(domFromByteArary, domDoc));
|
||||
|
||||
// Test overload taking a QIODevice
|
||||
QDomDocument domFromIODevice;
|
||||
QBuffer buffer(&byteArray);
|
||||
QVERIFY(buffer.open(QIODevice::ReadOnly));
|
||||
QVERIFY(domFromIODevice.setContent(&buffer));
|
||||
QVERIFY(compareDocuments(domFromIODevice, domDoc));
|
||||
}
|
||||
|
||||
void tst_QDom::setContentOverloads()
|
||||
{
|
||||
QDomDocument doc;
|
||||
QString errorMessage;
|
||||
|
||||
QByteArray data("<a>test</a>");
|
||||
QString text = QString::fromLatin1(data);
|
||||
QXmlStreamReader reader(data);
|
||||
|
||||
QBuffer buffer(&data);
|
||||
QVERIFY(buffer.open(QIODevice::ReadOnly));
|
||||
|
||||
QVERIFY(doc.setContent(data));
|
||||
QVERIFY(doc.setContent(data.data()));
|
||||
QVERIFY(doc.setContent(text));
|
||||
QVERIFY(doc.setContent(&reader));
|
||||
QVERIFY(doc.setContent(&buffer));
|
||||
buffer.reset();
|
||||
|
||||
// With parse options
|
||||
QVERIFY(doc.setContent(data, QDomDocument::ParseOption::Default));
|
||||
QVERIFY(doc.setContent(data.data(), QDomDocument::ParseOption::Default));
|
||||
QVERIFY(doc.setContent(text, QDomDocument::ParseOption::Default));
|
||||
QVERIFY(doc.setContent(&reader, QDomDocument::ParseOption::Default));
|
||||
QVERIFY(doc.setContent(&buffer, QDomDocument::ParseOption::Default));
|
||||
buffer.reset();
|
||||
|
||||
// With output param
|
||||
QVERIFY(doc.setContent(data, &errorMessage));
|
||||
QVERIFY(doc.setContent(text, &errorMessage));
|
||||
QVERIFY(doc.setContent(&buffer, &errorMessage));
|
||||
buffer.reset();
|
||||
// There's no setContent(QXmlStreamReader *, QString *, int *, int *) overload
|
||||
// QVERIFY(doc.setContent(&reader, &errorMessage));
|
||||
|
||||
// With namespace processing param
|
||||
QVERIFY(doc.setContent(data, false));
|
||||
QVERIFY(doc.setContent(text, false));
|
||||
QVERIFY(doc.setContent(&reader, false));
|
||||
QVERIFY(doc.setContent(&buffer, false));
|
||||
buffer.reset();
|
||||
|
||||
// With namespace processing and output params
|
||||
QVERIFY(doc.setContent(data, false, &errorMessage));
|
||||
QVERIFY(doc.setContent(text, false, &errorMessage));
|
||||
QVERIFY(doc.setContent(&reader, false, &errorMessage));
|
||||
QVERIFY(doc.setContent(&buffer, false, &errorMessage));
|
||||
buffer.reset();
|
||||
}
|
||||
|
||||
void tst_QDom::parseOptions()
|
||||
{
|
||||
QString input = u"<doc xmlns:ns='http://example.com/'>"
|
||||
"<ns:nested/>"
|
||||
"</doc>"_s;
|
||||
{
|
||||
QDomDocument document;
|
||||
QVERIFY(document.setContent(input, QDomDocument::ParseOption::Default));
|
||||
const QDomElement docElement = document.firstChildElement("doc");
|
||||
QVERIFY(!docElement.isNull());
|
||||
const QDomElement nestedElement = docElement.firstChildElement();
|
||||
QCOMPARE(nestedElement.nodeName(), "ns:nested");
|
||||
QVERIFY(!nestedElement.isNull());
|
||||
QVERIFY(nestedElement.localName().isEmpty());
|
||||
QVERIFY(nestedElement.prefix().isEmpty());
|
||||
QVERIFY(nestedElement.namespaceURI().isEmpty());
|
||||
}
|
||||
{
|
||||
QDomDocument document;
|
||||
QVERIFY(document.setContent(input, QDomDocument::ParseOption::UseNamespaceProcessing));
|
||||
const QDomElement docElement = document.firstChildElement("doc");
|
||||
QVERIFY(!docElement.isNull());
|
||||
const QDomElement nestedElement = docElement.firstChildElement("nested");
|
||||
QVERIFY(!nestedElement.isNull());
|
||||
QCOMPARE(nestedElement.nodeName(), "ns:nested");
|
||||
QCOMPARE(nestedElement.localName(), "nested");
|
||||
QCOMPARE(nestedElement.prefix(), "ns");
|
||||
QCOMPARE(nestedElement.namespaceURI(), "http://example.com/");
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDom::parseResult()
|
||||
{
|
||||
QString input = u"<doc xmlns:b='http://example.com/'>"
|
||||
"<b:element/>"_s;
|
||||
|
||||
QDomDocument document;
|
||||
QDomDocument::ParseResult result = document.setContent(input);
|
||||
QVERIFY(!result);
|
||||
QVERIFY(!result.errorMessage.isEmpty());
|
||||
QVERIFY(result.errorLine);
|
||||
QVERIFY(result.errorColumn);
|
||||
|
||||
input.append("</doc>");
|
||||
result = document.setContent(input);
|
||||
QVERIFY(result);
|
||||
QVERIFY(result.errorMessage.isEmpty());
|
||||
QVERIFY(!result.errorLine);
|
||||
QVERIFY(!result.errorColumn);
|
||||
}
|
||||
|
||||
void tst_QDom::toString_01_data()
|
||||
@ -1624,7 +1747,7 @@ void tst_QDom::checkLiveness() const
|
||||
void tst_QDom::reportDuplicateAttributes() const
|
||||
{
|
||||
QDomDocument dd;
|
||||
bool isSuccess = dd.setContent(QLatin1String("<test x=\"1\" x=\"2\"/>"));
|
||||
bool isSuccess = bool(dd.setContent(QLatin1String("<test x=\"1\" x=\"2\"/>")));
|
||||
QVERIFY2(!isSuccess, "Duplicate attributes are well-formedness errors, and should be reported as such.");
|
||||
}
|
||||
|
||||
@ -1892,7 +2015,7 @@ void tst_QDom::setContentWhitespace() const
|
||||
|
||||
QDomDocument domDoc;
|
||||
|
||||
QCOMPARE(domDoc.setContent(doc), expectedValidity);
|
||||
QCOMPARE(bool(domDoc.setContent(doc)), expectedValidity);
|
||||
|
||||
if(expectedValidity)
|
||||
QCOMPARE(domDoc.documentElement().nodeName(), QString::fromLatin1("e"));
|
||||
|
Loading…
Reference in New Issue
Block a user