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:

QXmlStreamWriter-写入

使用 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 元素并找到&lt;Column title="D"&gt; 元素。找到它后,readNextStartElement()skipCurrentElement() 的组合可用于读取其所有子元素。

假设您在示例中显示的 XML 文档可以从 xmlDocument 对象中读取。要通过适当的错误检查从 &lt;Column title="D"&gt; 元素中提取所有 &lt;item&gt; 元素,您可以执行以下操作:

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文件的主要内容,如果未能解决你的问题,请参考以下文章

QXmlStreamReader-解析xml文件

22.QT-QXmlStreamReader解析,QXmlStreamWriter写入

QXmlStreamReader/QXmlStreamWriter实现Qt下xml文件读写

QT开发(四十四)——流方法解析XML

Qt---Xml文件解析

如何在开始时设置 QXmlStreamReader?