使用TinyXML2在C ++中读取XML文件

问题描述 投票:1回答:2

我对在C ++中使用XML感到很陌生,我正在尝试解析要下载的文件列表。我正在使用的XML文件是通过PHP生成的,看起来像这样:

<?xml version="1.0"?>
<FileList>
  <File Name="xxx" Path="xxx" MD5="xxx" SHA1="xxx"/>
</FileList>

以下是我在C ++中使用的代码,这些代码是我通过一些在线教程(它包含在某些全局函数中)提出的:

tinyxml2::XMLDocument doc;
            doc.LoadFile("file_listing.xml");
            tinyxml2::XMLNode* pRoot = doc.FirstChild();
            tinyxml2::XMLElement* pElement = pRoot->FirstChildElement("FileList");
            if (pRoot == nullptr)
            {
                QString text = QString::fromLocal8Bit("Error text in french");
                //other stuff
            }
            else
            {
                tinyxml2::XMLElement* pListElement = pElement->FirstChildElement("File");
                while (pListElement != nullptr)
                {
                    QString pathAttr = QString::fromStdString(pListElement->Attribute("Path"));
                    QString md5Attr = QString:: fromStdString(pListElement->Attribute("MD5"));
                    QString sha1Attr = QString::fromStdString(pListElement->Attribute("SHA1"));

                    QString currentPath = pathAttr.remove("path");
                    QString currentMd5 = this->fileChecksum(currentPath, QCryptographicHash::Md5);
                    QString currentSha1 = this->fileChecksum(currentPath, QCryptographicHash::Sha1);

                    QFile currentFile(currentPath);

                    if (md5Attr != currentMd5 || sha1Attr != currentSha1 || !currentFile.exists())
                    {
                        QString url = "url" + currentPath;
                        this->downloadFile(url);
                    }

                    pListElement = pListElement->NextSiblingElement("File");
                }

问题是,我在下一行收到类似“访问冲突,这是nullptr”的错误:

tinyxml2 :: XMLElement * pListElement = pElement-> FirstChildElement(“ File”);

由于我在编码方面还远非专业人士,而且我已经在互联网上上下搜索,所以我希望这里的人能为我提供一些指导。

祝大家有美好的一天。

c++ tinyxml2
2个回答
1
投票

我不知道您是否有C ++ 17,但是可以通过使用auto*if-init-expressions消除很多噪音(或依赖于可以将指针隐式转换为布尔值的事实。)

代码的主要问题是您没有使用XMLElement*,而是使用了XMLNode。函数tinyxml2::XMLDocument::RootElement()自动为您获取最顶层的元素。

因为您在顶部有一个xml声明,所以FirstChild返回了……没有任何子代,因此其余代码将失败。

通过使用RootElement tinyxml知道跳过任何领先的非元素节点(注释,文档类型等),而是给您<FileList>


    tinyxml2::XMLDocument doc;
    auto err = doc.LoadFile("file_listing.xml");
    if(err != tinyxml2::XML_SUCCESS) {
        //Could not load file. Handle appropriately.
    } else {
        if(auto* pRoot = doc.RootElement(); pRoot == nullptr) {
            QString text = QString::fromLocal8Bit("Error text in french");
            //other stuff
        } else {
            for(auto* pListElement = pRoot->FirstChildElement("File");
                pListElement != nullptr;
                pListElement = pListElement->NextSiblingElement("File"))
            {
                QString pathAttr = QString::fromStdString(pListElement->Attribute("Path"));
                QString md5Attr = QString:: fromStdString(pListElement->Attribute("MD5"));
                QString sha1Attr = QString::fromStdString(pListElement->Attribute("SHA1"));

                QString currentPath = pathAttr.remove("path");
                QString currentMd5 = this->fileChecksum(currentPath, QCryptographicHash::Md5);
                QString currentSha1 = this->fileChecksum(currentPath, QCryptographicHash::Sha1);

                QFile currentFile(currentPath);
                if(md5Attr != currentMd5 || sha1Attr != currentSha1 || !currentFile.exists()) {
                    QString url = "url" + currentPath;
                    this->downloadFile(url);
                }
            }
        }
    }


1
投票

根据reference for tinyxml2::XMLNode FirstChild():

获取第一个子节点,如果不存在,则为null。

因此,此行将获得根节点:

tinyxml2::XMLNode* pRoot = doc.FirstChild();

意味着当您试图在根节点内找到FileList节点时,它返回null。

为了避免访问冲突,请在使用指针之前检查其是否有效。如果对pRoot进行了if检查,但在它尝试调用pRoot上的函数之前的那一行。如果没有检查pElement,那么这就是为什么出现访问冲突的原因。在检查指针是否有效的同时,请考虑在日志记录中添加else块,以说明发生了什么问题(例如“找不到元素X”)。从长远来看,这将为您提供帮助-XML解析是很痛苦的,即使使用Tinyxml这样的库,也总会遇到类似的麻烦问题,因此养成检查指针的习惯并注销有用的消息肯定会有所回报。] >

© www.soinside.com 2019 - 2024. All rights reserved.