QXmlStreamReader-解析xml文件
Posted 一头秀发的程序猿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QXmlStreamReader-解析xml文件相关的知识,希望对你有一定的参考价值。
QXmlStreamReader类提供了一个快速解析器,用于通过简单的流API读取格式良好的XML。逐层读取,递归下降解析。
可到Qt助手文档查看QXmlStream Bookmarks Example。
MyTest:
void readConfig(QString& filename)
QFile file(filename);
if(!file.exists())
return;
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QXmlStreamReader(&file);
while(!xmlReader.atEnd() && !xmlReader.hasError())
xmlReader.readNextStartElement();
if(xmlReader.isStartElement())
qDebug()<<xmlReader.name().toString(); //tagName
qDebug()<<xmlReader.attributes().value("type").toString(); //属性值
创建xml文档,写入xml:
使用 QXmlStreamReader 解析 XML
【中文标题】使用 QXmlStreamReader 解析 XML【英文标题】:Parse XML with QXmlStreamReader 【发布时间】:2014-02-17 11:52:16 【问题描述】:我用QXmlStreamWriter
创建了这个xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<Draw>
<Input>
<Column title="A"/>
<Column title="B"/>
<Column title="C"/>
<Column title="D">
<item id="0">Bayer Leverkusen</item>
<item id="1">Benfica</item>
<item id="2">Villareal</item>
<item id="3">Montpellier</item>
</Column>
</Input>
</Draw>
我想创建一个包含标签Column title="D"
内所有项目的字符串向量:现在,我知道如何创建QVector
以及它们如何适合内部元素,我只需要弄清楚如何我可以通过从 xml 文件中推断信息来做到这一点。
你能帮帮我吗?
【问题讨论】:
对于像这样更复杂的 xml 解析,您可以尝试在 Qt qt-project.org/doc/qt-4.8/xmlprocessing.html 中使用 XQuerys。要使用它们,您需要在 .pro 文件中启用 xmlpatters (QT += xmlpatterns) 【参考方案1】:您可以使用QXmlStreamReader
遍历XML 元素并找到<Column title="D">
元素。找到它后,readNextStartElement()
与 skipCurrentElement()
的组合可用于读取其所有子元素。
假设您在示例中显示的 XML 文档可以从 xmlDocument
对象中读取。要通过适当的错误检查从 <Column title="D">
元素中提取所有 <item>
元素,您可以执行以下操作:
QXmlStreamReader xmlIterator(xmlDocument);
QVector<QString> output;
for(; !xmlIterator.atEnd(); xmlIterator.readNext())
if(isStartElementOfColumnD(xmlIterator))
while(xmlIterator.readNextStartElement())
if(isItemElement(xmlIterator))
output.append(xmlIterator.readElementText());
else
xmlIterator.skipCurrentElement();
if(xmlIterator.hasError())
qCritical() << "Error has occurred:" << xmlIterator.errorString();
else
qDebug() << output;
在上面的示例中,我使用了两个谓词来隐藏xmlIterator
的冗长且难以阅读的验证。它们如下:
inline bool isStartElementOfColumnD(const QXmlStreamReader& xmlIterator)
return xmlIterator.isStartElement() && xmlIterator.name() == "Column" &&
xmlIterator.attributes().value("title") == "D";
inline bool isItemElement(const QXmlStreamReader& xmlIterator)
return xmlIterator.name() == "item" &&
xmlIterator.attributes().hasAttribute("id");
示例结果:
QVector("Bayer Leverkusen", "Benfica", "Villareal", "Montpellier")
【讨论】:
【参考方案2】:我会这样写:
QVector<QString> store;
[..]
if (reader.readNextStartElement() && reader.name() == "Draw")
while (reader.readNextStartElement() && reader.name() == "Input")
while (reader.readNextStartElement())
QXmlStreamAttributes attr = reader.attributes();
if (reader.name() == "Column" && attr.value("title").toString() == "D")
while(!(reader.isEndElement() && reader.name() == "Column"))
if (reader.isStartElement() && reader.name() == "item")
QString text = reader.readElementText();
store.append(text);
reader.readNext();
if (reader.hasError())
// Handle error.
QString msg = reader.errorString();
break;
else
reader.readNext();
else
reader.raiseError("Expected <Draw> element");
[..]
【讨论】:
最里面的while循环看起来会在解析错误的情况下永远循环。以上是关于QXmlStreamReader-解析xml文件的主要内容,如果未能解决你的问题,请参考以下文章
22.QT-QXmlStreamReader解析,QXmlStreamWriter写入