diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index c6d085714fb..eebccc6cc5d 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -827,6 +827,7 @@ void QXmlStreamReaderPrivate::init() isWhitespace = true; isCDATA = false; standalone = false; + hasStandalone = false; tos = 0; resumeReduction = 0; state_stack[tos++] = 0; @@ -1777,7 +1778,6 @@ void QXmlStreamReaderPrivate::startDocument() * proper order: * * [23] XMLDecl ::= '' */ - bool hasStandalone = false; for (qsizetype i = 0; err.isNull() && i < n; ++i) { Attribute &attrib = attributeStack[i]; diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h index b1fee62e04d..ffa49f8c642 100644 --- a/src/corelib/serialization/qxmlstream_p.h +++ b/src/corelib/serialization/qxmlstream_p.h @@ -383,6 +383,7 @@ public: uint hasExternalDtdSubset : 1; uint lockEncoding : 1; uint namespaceProcessing : 1; + uint hasStandalone : 1; // TODO: expose in public API int resumeReduction; void resume(int rule); @@ -509,6 +510,8 @@ public: QXmlStreamEntityResolver *entityResolver; + static QXmlStreamReaderPrivate *get(QXmlStreamReader *q) { return q->d_func(); } + private: /*! \internal Never assign to variable type directly. Instead use this function. diff --git a/src/xml/dom/qdomhelpers.cpp b/src/xml/dom/qdomhelpers.cpp index 62258fbdfd3..48869907f8f 100644 --- a/src/xml/dom/qdomhelpers.cpp +++ b/src/xml/dom/qdomhelpers.cpp @@ -8,6 +8,7 @@ #include "qdomhelpers_p.h" #include "qdom_p.h" #include "qxmlstream.h" +#include "private/qxmlstream_p.h" #include #include @@ -264,9 +265,10 @@ bool QDomParser::parseProlog() if (reader->isStandaloneDocument()) { value += u" standalone='yes'"_s; } else { - // TODO: Add standalone='no', if 'standalone' is specified. With the current - // QXmlStreamReader there is no way to figure out if it was specified or not. - // QXmlStreamReader needs to be modified for handling that case correctly. + // Add the standalone attribute only if it was specified + QXmlStreamReaderPrivate *priv = QXmlStreamReaderPrivate::get(reader); + if (priv->hasStandalone) + value += u" standalone='no'"_s; } if (!domBuilder.processingInstruction(u"xml"_s, value)) { diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp index cfc869949f4..4cf48a9f4b0 100644 --- a/tests/auto/xml/dom/qdom/tst_qdom.cpp +++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp @@ -105,6 +105,7 @@ private slots: void DTDInternalSubset() const; void DTDInternalSubset_data() const; void QTBUG49113_dontCrashWithNegativeIndex() const; + void standalone(); void cleanupTestCase() const; @@ -2225,6 +2226,31 @@ void tst_QDom::QTBUG49113_dontCrashWithNegativeIndex() const QVERIFY(node.isNull()); } +void tst_QDom::standalone() +{ + { + QDomDocument doc; + const QString dtd("\n" + "\n"); + doc.setContent(dtd); + QVERIFY(doc.toString().contains("standalone=\'no\'")); + } + { + QDomDocument doc; + const QString dtd("\n" + "\n"); + doc.setContent(dtd); + QVERIFY(!doc.toString().contains("standalone")); + } + { + QDomDocument doc; + const QString dtd("\n" + "\n"); + doc.setContent(dtd); + QVERIFY(doc.toString().contains("standalone=\'yes\'")); + } +} + void tst_QDom::DTDInternalSubset() const { QFETCH( QString, doc );