首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C++读取TinyXML2文件

用C++读取TinyXML2文件
EN

Stack Overflow用户
提问于 2020-06-02 19:18:33
回答 2查看 957关注 0票数 1

我对在C++中使用XML非常陌生,我正试图解析要下载的文件列表。我使用的THe XML文件是通过PHP生成的,如下所示:

代码语言:javascript
复制
<?xml version="1.0"?>
<FileList>
  <File Name="xxx" Path="xxx" MD5="xxx" SHA1="xxx"/>
</FileList>

我在C++中使用的代码如下,我使用了一些在线教程(它包含在一些全局函数中):

代码语言:javascript
复制
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");

由于我在编码方面不是一个专业人士,而且我已经上下搜索过互联网,我希望这里的人能给我一些指点。

祝大家今天愉快。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-06-02 23:48:12

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

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

因为在顶部有一个xml声明,所以FirstChild返回that...which没有任何子元素,所以其余的代码都失败了。

通过使用RootElement,tinyxml知道跳过任何领先的非元素节点(注释、doctype等)。然后给你<FileList>代替。

代码语言:javascript
复制
    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
EN

Stack Overflow用户

发布于 2020-06-02 23:02:33

根据tinyxml2 2::XMLNode的参考FirstChild():

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

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

代码语言:javascript
复制
tinyxml2::XMLNode* pRoot = doc.FirstChild();

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

要避免访问冲突,请在使用指针之前检查它们是否有效。对于pRoot有一个if检查,但在它试图调用pRoot上的函数之前的行。没有是否检查pElement,所以这就是为什么会出现访问冲突。除了检查指针是有效的,还可以考虑添加带有日志记录的其他块,以说明出了什么问题(例如,“未能找到元素X")。从长远来看,这将对您有所帮助-- XML解析是一项痛苦的工作,即使使用像Tinyxml这样的库,也总是会出现这样的初始问题,因此养成checki指针的习惯并注销有用的消息肯定会有回报。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62159742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档