为什么可以';我是否使用Qt中的QXmlStreamReader解析XML文件? 我试图弄清楚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> 约翰 雌鹿 厕所。doe@example.com http://en.wikipedia.org/wiki/John_Doe 简 雌鹿 简。doe@example.com http://en.wikipedia.org/wiki/John_Doe 马蒂 梅卡莱宁 马蒂。meikalainen@example.com http://fi.wikipedia.org/wiki/Matti_Meikäläinen

为什么可以';我是否使用Qt中的QXmlStreamReader解析XML文件? 我试图弄清楚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> 约翰 雌鹿 厕所。doe@example.com http://en.wikipedia.org/wiki/John_Doe 简 雌鹿 简。doe@example.com http://en.wikipedia.org/wiki/John_Doe 马蒂 梅卡莱宁 马蒂。meikalainen@example.com http://fi.wikipedia.org/wiki/Matti_Meikäläinen,c++,xml,qt,qt4,xml-parsing,C++,Xml,Qt,Qt4,Xml Parsing,…我正试图用以下代码解析它: 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); bo

…我正试图用以下代码解析它:

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;
}
intmain(intargc,char*argv[])
{
如果(argc!=2)返回1;
QString文件名(argv[1]);
QTextStream cout(stdout);

cout您确定您的文档是UTF-8编码的吗?您使用了什么编辑器?如果您不解码查看文件,请检查ä-字符的外观。

文件不是UTF-8编码的。将编码更改为iso-8859-1,它将无误地进行解析

<?xml version="1.0" encoding="iso-8859-1" ?>

关于编码:正如baysmith和hmuelner所说,您的文件可能编码不正确(除非粘贴到此处时编码丢失)。请尝试使用一些高级文本编辑器修复此问题


使用text()的问题在于,它不能按预期工作。text()返回当前标记的内容(如果它是字符、注释、DTD或EntityReference类型)。当前标记是StartElement,因此为空。如果要使用/读取当前StartElement的文本,请使用readElementText()相反。

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

  • 该文件实际上不是UTF-8编码的。我将编码更改为iso-8859-1,编码警告消失
  • text()函数无法按预期工作。我必须使用readElementText()读取条目的内容
  • 当我尝试在不包含文本的元素上读取ElementText()时(如本例中的顶级元素),解析器返回“预期的字符数据”错误,解析被中断。我发现这种行为很奇怪(我认为返回空字符串并继续会更好)但是我想只要规范是已知的,我就可以解决它,避免在每个条目上调用这个函数
  • 按预期工作的相关代码部分如下所示:

    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;
    }
    
    while(!xml.atEnd()&&&!xml.hasError())
    {
    readNext();
    if(xml.isStartElement())
    {
    QString name=xml.name().toString();
    如果(姓名==“名字”| |姓名==“姓氏”| |
    姓名==“电子邮件”| |姓名==“网站”)
    {
    
    试试这个例子,我刚从我的项目中复制了它,它对我有用

    void MainWindow::readXML(const QString &fileName)
    {
    
    
    fileName = "D:/read.xml";
    
    QFile* file = new QFile(fileName);
    if (!file->open(QIODevice::ReadOnly | QIODevice::Text))
    {
         QMessageBox::critical(this, "QXSRExample::ReadXMLFile", "Couldn't open xml file", QMessageBox::Ok);
         return;
    }
    
    /* QXmlStreamReader takes any QIODevice. */
    QXmlStreamReader xml(file);
    /* We'll parse the XML until we reach end of it.*/
    while(!xml.atEnd() && !xml.hasError())
    {
        /* Read next element.*/
        QXmlStreamReader::TokenType token = xml.readNext();
        /* If token is just StartDocument, we'll go to next.*/
        if(token == QXmlStreamReader::StartDocument)
            continue;
    
        /* If token is StartElement, we'll see if we can read it.*/
        if(token == QXmlStreamReader::StartElement) {
            if(xml.name() == "email") {
                ui->listWidget->addItem("Element: "+xml.name().toString());
                continue;
            }
        }
    }
    /* Error handling. */
    if(xml.hasError())
        QMessageBox::critical(this, "QXSRExample::parseXML", xml.errorString(), QMessageBox::Ok);
    
    //resets its internal state to the initial state.
    xml.clear();
    }
    
    void MainWindow::writeXML(const QString &fileName)
    {
    fileName = "D:/write.xml";
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
         QMessageBox::critical(this, "QXSRExample::WriteXMLFile", "Couldn't open anna.xml", QMessageBox::Ok);
         return;
    }
    QXmlStreamWriter xmlWriter(&file);
    xmlWriter.setAutoFormatting(true);
    xmlWriter.writeStartDocument();
    //add Elements
    xmlWriter.writeStartElement("bookindex");
    ui->listWidget->addItem("bookindex");
    xmlWriter.writeStartElement("Suleman");
    ui->listWidget->addItem("Suleman");
    
    //write all elements in xml filexl
    xmlWriter.writeEndDocument();
    file.close();
    if (file.error())
        QMessageBox::critical(this, "QXSRExample::parseXML", file.errorString(), QMessageBox::Ok);
    
    
    }
    

    我做了更多的研究,编码不是空的,如果我在访问encoding()之前执行readNext(),则显示为“UTF-8”。没错。我很惭愧我没有想到这一点。:(但是如果没有指定XML编码呢?QXmlStreamReader是否假设它是UTF-8?也就是说,在XML文件的顶部有以下内容:
    “遇到编码错误的内容。”很有意思。是的,readElementText()通常有点问题。从数据可能不完整的流(例如套接字)增量读取数据时,它也不能正常工作,请看我是否应该将此报告为错误?我不确定它是否是错误,或者它是否应该以这种方式工作。@Frankosterfield在
    readElementText()
    上是否有新功能?是否有任何函数检查它是否工作?