c++ - 为什么我不能使用 Qt 中的 QXmlStreamReader 解析 XML 文件?

标签 c++ xml qt qt4 xml-parsing

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

<?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>

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

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;
}

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

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

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

最佳答案

我自己回答这个问题,因为这个问题与三个问题有关,其中两个是在回复中提到的。

  1. 该文件实际上不是 UTF-8 编码的。我将编码更改为 iso-8859-1,编码警告消失了。
  2. text() 函数没有像我预期的那样工作。我必须使用 readElementText() 来读取条目的内容。
  3. 当我尝试在不包含文本的元素上读取 ElementText() 时,例如在我的例子中是顶级 ,解析器返回一个 "Expected character data " 错误,解析中断。我发现这种行为很奇怪(在我看来返回一个空字符串并继续会更好)但我想只要规范已知,我就可以解决它并避免在每个条目上调用此函数。

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

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;
}

关于c++ - 为什么我不能使用 Qt 中的 QXmlStreamReader 解析 XML 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4201175/

相关文章:

xml - 格式化使用 Oracle XMLAgg 生成的 XML 字符串

Qt 编码问题

android - QAbstractButton 和 QPushButton* 之间的比较缺少强制转换

C++:类和构造函数:使用初始化列表来初始化字段

c++ - std::numeric_limits<int>::has_infinity + 条件三元运算符

java - 使用 ViewPager 在 Fragment 中创建 Listview

python - 将字符串作为项目添加到 QT/Python 中的 qtableWidget

c++ - 从 std::string_view 派生的对象的比较在 MSVC 中不明确

c++ - 为什么空IP地址将计算机名解析为204.204.204.204?

android - 元数据标签没有正确的值