为什么我不能使用 Qt 中的 QXmlStreamReader 解析 XML 文件? [英] Why can't I parse a XML file using QXmlStreamReader from Qt?

查看:30
本文介绍了为什么我不能使用 Qt 中的 QXmlStreamReader 解析 XML 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试弄清楚 QXmlStreamReader 如何为我正在编写的 C++ 应用程序工作.我要解析的 XML 文件是一个大字典,具有复杂的结构和大量的 Unicode 字符,因此我决定尝试使用更简单的文档创建一个小测试用例.不幸的是,我撞到了墙.这是示例 xml 文件:

I'm trying to figure out how QXmlStreamReader works for a C++ application I'm writing. The XML file I want to parse is a large dictionary with a convoluted structure and plenty of Unicode characters so I decided to try a small test case with a simpler document. Unfortunately, I hit a wall. Here's the example xml file:

<?xml version="1.0" encoding="UTF-8" ?>
<persons>
    <person>
        <firstname>John</firstname>
        <surname>Doe</surname>
        <email>john.doe@example.com</email>
        <website>http://en.wikipedia.org/wiki/John_Doe</website>
    </person>
    <person>
        <firstname>Jane</firstname>
        <surname>Doe</surname>
        <email>jane.doe@example.com</email>
        <website>http://en.wikipedia.org/wiki/John_Doe</website>
    </person>
    <person>
        <firstname>Matti</firstname>
        <surname>Meikäläinen</surname>
        <email>matti.meikalainen@example.com</email>
        <website>http://fi.wikipedia.org/wiki/Matti_Meikäläinen</website>
    </person>
</persons>

...我正在尝试使用以下代码解析它:

...and I'm trying to parse it using this code:

int main(int argc, char *argv[])
{
    if (argc != 2) return 1;

    QString filename(argv[1]);
    QTextStream cout(stdout);
    cout << "Starting... filename: " << filename << endl;

    QFile file(filename);
    bool open = file.open(QIODevice::ReadOnly | QIODevice::Text);
    if (!open) 
    {
        cout << "Couldn't open file" << endl;
        return 1;
    }
    else 
    {
        cout << "File opened OK" << endl;
    }

    QXmlStreamReader xml(&file);
    cout << "Encoding: " << xml.documentEncoding().toString() << endl;

    while (!xml.atEnd() && !xml.hasError()) 
    {
        xml.readNext();
        if (xml.isStartElement())
        {
            cout << "element name: '" << xml.name().toString() << "'" 
                << ", text: '" << xml.text().toString() << "'" << endl;
        }
        else if (xml.hasError())
        {
            cout << "XML error: " << xml.errorString() << endl;
        }
        else if (xml.atEnd())
        {
            cout << "Reached end, done" << endl;
        }
    }

    return 0;
}

...然后我得到这个输出:

...then I get this output:

C:\xmltest\Debug>xmltest.exe example.xml
开始...文件名:example.xml
文件打开正常
编码:
XML 错误:遇到编码不正确的内容.

C:\xmltest\Debug>xmltest.exe example.xml
Starting... filename: example.xml
File opened OK
Encoding:
XML error: Encountered incorrectly encoded content.

发生了什么?这个文件再简单不过了,对我来说看起来很一致.对于我的原始文件,我也得到了一个空白的编码条目,显示了条目的名称(),但唉,文本()也是空的.非常感谢任何建议,我个人非常困惑.

What happened? This file couldn't be simpler and it looks consistent to me. With my original file I also get a blank entry for the encoding, the entries' names() are displayed, but alas, the text() is also empty. Any suggestions greatly appreciated, personally I'm thorougly mystified.

推荐答案

我自己回答这个问题,因为这个问题与三个问题有关,其中两个是由回复提出的.

I'm answering this myself as this problem was related to three issues, two of which were brought up by the responses.

  1. 该文件实际上不是 UTF-8 编码的.我将编码更改为 iso-8859-1,编码警告消失了.
  2. text() 函数没有按照我的预期工作.我必须使用 readElementText() 来读取条目的内容.
  3. 当我尝试在不包含文本的元素上读取元素文本()时,例如在我的例子中是顶级 <persons>,解析器返回一个 "预期字符data" 错误,解析中断.我发现这种行为很奇怪(我认为返回一个空字符串并继续会更好)但我想只要规范已知,我就可以解决它并避免在每个条目上调用此函数.
  1. The file actually wasn't UTF-8 encoded. I changed the encoding to iso-8859-1 and the encoding warning disappeared.
  2. The text() function doesn't work as I expected. I have to use readElementText() to read the entries' contents.
  3. When I try to readElementText() on an element that doesn't contain text, like the top-level <persons> in my case, the parser returns an "Expected character data" error and the parsing is interrupted. I find this behaviour strange (in my opinion returning an empty string and continuing would be better) but I guess as long as the specification is known, I can work around it and avoid calling this function on every entry.

按预期工作的相关代码部分现在如下所示:

The relevant code section that works as expected now looks like this:

while (!xml.atEnd() && !xml.hasError()) 
{
    xml.readNext();
    if (xml.isStartElement())
    {
        QString name = xml.name().toString();
        if (name == "firstname" || name == "surname" || 
            name == "email" || name == "website")
        {
            cout << "element name: '" << name  << "'" 
                         << ", text: '" << xml.readElementText() 
                         << "'" << endl;
        }
    }
}
if (xml.hasError())
{
    cout << "XML error: " << xml.errorString() << endl;
}
else if (xml.atEnd())
{
    cout << "Reached end, done" << endl;
}

这篇关于为什么我不能使用 Qt 中的 QXmlStreamReader 解析 XML 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆