summaryrefslogtreecommitdiffstats
path: root/src/xml/dom/qdom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xml/dom/qdom.cpp')
-rw-r--r--src/xml/dom/qdom.cpp242
1 files changed, 194 insertions, 48 deletions
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 9c4f3653f8..f4c49c5e8c 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -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);
}
/*!