gpt4 book ai didi

c++ - Qt QXmlStreamReader 访问冲突

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:50:09 27 4
gpt4 key购买 nike

我正在使用 Qt 5.11.1(MSVSC2015 32 位)和 QtCreator 4.6.2。我在使用 QXmlStreamReader 解析 XML 时遇到问题。代码是根据Qt's example编写的.执行我的代码时,它会在 QIODevice.cpp 的 checkWarnMessage 函数中产生访问冲突。这image显示调用堆栈和发生访问冲突的确切行。

实际的 XML 更复杂并且具有嵌套元素。解析 XML 的函数的实现方式与 Qt 示例中的 void XbelReader::readXBEL() 函数相同(根据元素名称调用适当的函数来解析该元素)。但是通过这个简单的例子,我成功地重现了我在实际解决方案中遇到的问题。

XML 是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
<element1>1</element1>
<element2>2</element2>
<element3>3</element3>
<element4>4</element4>
<element5>5</element5>
<element6>6</element6>
</root>

解析此 XML 的代码是:

#include <string>
#include <stdexcept>
#include <iostream>

#include <QCoreApplication>
#include <QXmlStreamReader>
#include <QFile>
#include <QString>

#define ASSERT_ELEMENT_NAME(NAME) Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == NAME);

using namespace std;

void OpenFile(const QString& fileName, QXmlStreamReader& xmlReader)
{
QFile configFile(fileName);
if (configFile.open(QFile::ReadOnly | QFile::Text) == false)
throw runtime_error(string("Failed to open file: ") + configFile.errorString().toStdString());

xmlReader.setDevice(&configFile);
if (xmlReader.readNextStartElement() == false)
throw runtime_error("File does not have root element");

if (xmlReader.name() != "root")
throw runtime_error("File has invalid root element");
}

void ParseElement1(QXmlStreamReader& xmlReader)
{
ASSERT_ELEMENT_NAME("element1");

auto text = xmlReader.readElementText().trimmed();
auto isOk = false;
auto value = text.toInt(&isOk);

if (isOk == false)
throw runtime_error(string("invalid value: ") + text.toStdString());
else
cout << "element1: " << value << endl;
}

void ParseElement2(QXmlStreamReader& xmlReader)
{
ASSERT_ELEMENT_NAME("element2");

auto text = xmlReader.readElementText().trimmed();
auto isOk = false;
auto value = text.toInt(&isOk);

if (isOk == false)
throw runtime_error(string("invalid value: ") + text.toStdString());
else
cout << "element2: " << value << endl;
}

int main()
{
QXmlStreamReader xmlReader;

OpenFile("config.xml", xmlReader);

while(xmlReader.readNextStartElement())
{
if(xmlReader.name() == "element1")
ParseElement1(xmlReader);
if(xmlReader.name() == "element2")
ParseElement2(xmlReader);
else
xmlReader.skipCurrentElement();
}
}

如果我在主函数中注释两行:

        if(xmlReader.name() == "element2")
ParseElement2(xmlReader);

不会发生访问冲突。

我真的不知道我做错了什么。还是 QXmlStreamReader 中存在错误?我认为即使我做错了什么,访问冲突也不应该发生在 Qt 的库中。

整个项目(XmlParser.pro、main.cpp 和 config.xml)可以从此link下载

编辑

我已经按照 Manthan 的建议修复了我的示例,并且它按预期工作。我在 XML 中又添加了一件事。我在 element1 之前添加了大型多行注释。注释本身有 8019 个字符,包括空白字符,而整个 XML 文件有 8266 个字符。

XML 现在看起来像

<?xml version="1.0" encoding="UTF-8"?>
<root>
<!--
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment, comment,
comment, comment, co
-->
<element1>1</element1>
<element2>2</element2>
<element3>3</element3>
<element4>4</element4>
<element5>5</element5>
<element6>6</element6>
</root>

我已经使用 XML 工具插件以及 xmlvalidation.xml 检查了 XML 在 Notepad++ 中是否有效。当我使用新的 XML 执行固定示例时,我再次在先前链接的图像上描述的完全相同的位置发生访问冲突。

现在,如果我从 XML 注释中删除最后一个“o”字符(或从注释中删除任何其他字符,或者例如从 element6 的文本中删除“6”,或者实际上从 XML 中删除任何字符,同时保持 XML 有效) ,示例执行成功。这是我原来的问题。我的原始 XML 文件中有很多注释,导致文件大于 8KB。目前,作为解决方法,我删除评论以避免访问冲突。

我不清楚评论(或文件)长度如何导致访问冲突。

整个项目可以从这个link下载

最佳答案

问题出在 while 循环中。更新如下。

while(xmlReader.readNextStartElement())
{
if(xmlReader.name() == "element1")
ParseElement1(xmlReader);
else if(xmlReader.name() == "element2")
ParseElement2(xmlReader);
else
xmlReader.skipCurrentElement();
}

在您的代码中,第一个元素的类型为“element1”,然后首先处理(使用第一个 if),然后再次到达 else 并尝试跳过它,这会导致问题。

关于c++ - Qt QXmlStreamReader 访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51978938/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com