为什么tinyxml的FirstAttribute()在简单函数中返回null?

时间:2014-01-11 23:18:09

标签: c++ xml tinyxml

运行:Linux Mint 16,QtCreator 3.0.0,Qt 5.2.0。 tinyXML最新版本。

使用XML:

<users>
<user>
    <username>testadmin</username>
    <password>testpwd</password>
    <privileges>2</privileges>
</user>
<user>
    <username>testuser</username>
    <password>testpwd</password>
    <privileges>1</privileges>
</user>

无效的代码:

void Server::loadUsersFile()
{
TiXmlDocument usersDoc("users.xml");
    bool loadOk = usersDoc.LoadFile();

    if(!loadOk) {
        cout << "Error opening users file" << endl;
        return;
    }

    TiXmlElement* rootChild = usersDoc.FirstChildElement("users");
    TiXmlElement* userChild = rootChild->FirstChildElement("user");
    TiXmlAttribute* pAttrib=userChild->FirstAttribute();
    cout << pAttrib->Name();
}

pAttrib是NULL,我无法理解为什么。也许我没有得到Child / Attribute关系。帮助赞赏。

3 个答案:

答案 0 :(得分:2)

您的第一个user元素没有任何属性。属性是在元素的开始标记中定义的数据,因此要使user元素具有属性,它必须看起来像

<user type="posix">
...
</user>

其中type="posix"user元素的属性。

要获取元素中的username元素,可能需要

TiXmlElement* username = userChild->FirstChildElement();

或更安全

TiXmlElement* username = userChild->FirstChildElement("username");

答案 1 :(得分:2)

您的XML 没有任何属性。它在元素中包含文本,但没有属性

如果你的XML有类似的东西:

<user name="foo" />

然后它会给你一个属性。当然,你可以拥有多个属性:

<user username="testadmin" password="testpassword" privileges="2" />

您可以更改代码,也可以将XML更改为使用属性。如果您这样做,我建议您要求特定的属性,而不是要求用户名是 first 属性,例如。

如果您要使用XML,那么了解术语非常重要,否则您会感到非常困惑。在进一步深入之前,可能值得查看XML教程。

答案 2 :(得分:1)

我决定坚持使用“文本内部元素”版本,因为它似乎更容易阅读。谢谢您的帮助!所以,代码是:

void Server::loadUsersFile()
{
    cout << "Loading users list..."<<endl;

    TiXmlDocument usersDoc(this->fileUsersStr);
    bool loadOk = usersDoc.LoadFile();

    if(!loadOk) {
        cout << "Error opening users file" << endl;
        return;
    }
    TiXmlElement* rootChild = usersDoc.FirstChildElement("users");
    TiXmlElement* userChild = rootChild->FirstChildElement("user");

    TiXmlElement *usernameElem;
    TiXmlElement *passwordElem;
    TiXmlElement *privilegesElem;

    while(userChild)
    {
        usernameElem = userChild->FirstChildElement("username");
        passwordElem = userChild->FirstChildElement("password");
        privilegesElem = userChild->FirstChildElement("privileges");

        cout << "username: " << usernameElem->GetText() << endl;
        cout << "password: " << passwordElem->GetText() << endl;
        cout << "privilege:" << atoi(privilegesElem->GetText()) << endl;

        userChild = userChild->NextSiblingElement();
    }

    cout << "Finished loading."<<endl;
}