gpt4 book ai didi

c++ - 无法使用 QXmlStreamReader 识别空元素

转载 作者:太空宇宙 更新时间:2023-11-04 11:41:24 26 4
gpt4 key购买 nike

我在使用 Qt QXmlStreamReader (Qt 4.8.1) 检测空元素时遇到了一些问题。有一个 XML 文件包含以下部分

<Groups Number="4">
<Group Id="0" GroupName="Chambers">
<MemberChannels>4,5,6,7,8,9,10,11</MemberChannels>
<AverageShown>true</AverageShown>
</Group>
<Group Id="1" GroupName="Fluids">
<MemberChannels>0,1,17,18</MemberChannels>
<AverageShown>false</AverageShown>
</Group>
<Group Id="2"/>
<Group Id="3"/>
</Groups>

可以看到,Id为2和3的元素除了属性之外都是空的。该属性不会改变任何东西。如果它不在元素中,问题仍然存在。

这是使用QXmlStreamReader的解析代码,我简化了,所以可能编译不通过。只是您了解了基本概念。

[...]
QXmlStreamReader* m_poStreamReader = new QXmlStreamReader;
[...]

if(m_poStreamReader->readNextStartElement() && m_poStreamReader->name().toString() == "Group") {
this->parseGroupElement();
}

[...]

bool CTempscanXmlParser::parseGroupElement( void ) {
TGroupElement tElement;
if(m_poStreamReader->isStartElement() && !m_poStreamReader->isEndElement()) { // not empty
TGroupElement tElement = this->readGroupElement();
} else if(m_poStreamReader->isStartElement() && m_poStreamReader->isEndElement()) { // empty
tElement.oGroupName = QString::null;
}
[...]
}

文档说:

Empty elements are also reported as StartElement, followed directly by EndElement.

我可以使用 readNext() 并且仍然没有收到结束元素。似乎解析器只能检测

<tag></tag>

作为空元素但不是

<tag/>

所以,是我的问题还是 Qt 中存在问题?如果是这样,我如何检测不包含 2 个独立元素(开始/结束)的空元素?

编辑:所以 Huytard 向我要了一个工作示例。但他的回答让我找到了一个几乎回答了我的问题的解决方案。因此,我在我的回答中放了一个明确的例子。

最佳答案

感谢 Huytard,我认识到这只是 QXmlStreamReader::readNextStartElement 的行为有点出乎意料。我所期望的是,它真的只会读取 start 元素。最初我想事先检查一个元素是否为空,然后决定如何处理它的内容。这似乎是不可能的。我自己引用的文档涵盖了这种可能性。 IE。即使一个原子元素是空的,它实际上后面跟着一个实际上是结束元素的开始元素。这很糟糕,因为您无法在流中返回。

根据他的回答,我写了一个小例子来澄清(抱歉)并回答我原来的问题。

  const QString XML_STR = "<Groups Number=\"4\">" \
"<Group Id=\"0\" GroupName=\"Chambers\">" \
"<MemberChannels>4,5,6,7,8,9,10,11</MemberChannels>" \
"<AverageShown>true</AverageShown>" \
"</Group>" \
"<Group Id=\"1\"/>" \
"<Group Id=\"2\"/>" \
"</Groups>";

int main(int /* argc */, char** /* argv[] */)
{

qDebug() << "the way it would have made sense to me:";
{
QXmlStreamReader reader(XML_STR);

while(!reader.atEnd())
{
reader.readNextStartElement();
QString comment = (reader.isEndElement()) ? "is empty" : "has children";
qDebug() << reader.name() << comment;
}
}

qDebug() << "\napproximation to the way it should probably be done:";
{
QXmlStreamReader reader(XML_STR);

bool gotoNext = true;
while(!reader.atEnd())
{
if(gotoNext) {
reader.readNextStartElement();
}
QString output = reader.name().toString();
reader.readNext();
if(reader.isEndElement()) {
output += " is empty";
gotoNext = true;
} else {
output += " has children";
gotoNext = false;
}
qDebug() << output;
}
}

return 0;
}

这导致以下输出

  #they way it would have made sense to me: 
"Groups" "has children"
"Group" "has children"
"MemberChannels" "has children"
"MemberChannels" "is empty"
"AverageShown" "has children"
"AverageShown" "is empty"
"Group" "is empty"
"Group" "has children"
"Group" "is empty"
"Group" "has children"
"Group" "is empty"
"Groups" "is empty"
"" "has children"
# this has all been plain wrong

#approximation to the way it should probably be done:
"Groups has children"
"Group has children"
"MemberChannels has children"
" is empty" # ... but not a start element
"AverageShown has children"
" is empty"
"Group has children" # still wrong! this is an end element
"Group is empty"
"Group is empty"
"Groups has children" # ditto

我还是不喜欢。这种工作方式我需要对所有降低代码可读性的内容进行三次检查。

关于c++ - 无法使用 QXmlStreamReader 识别空元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21280705/

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