Need some help with TinyXML

This is a discussion on Need some help with TinyXML within the C++ Programming forums, part of the General Programming Boards category; Hello, I need some help figuring out how to read the next element on the list. I first need to ...

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    38

    Need some help with TinyXML

    Hello, I need some help figuring out how to read the next element on the list. I first need to get out of the <Account> loop though, but i tired using break, but it doesn't work.

    I kept getting an error when my parser get to <VirtualUser>.

    Currently my code looks like this:

    Code:
    #include <iostream>
    #include <string>
    #include "tinyxml.h"
    using std::cout;
    using std::string;
    using namespace std;
    int main() {
        string file = "test7.xml";
        TiXmlDocument doc(file.c_str());
        if (doc.LoadFile()) {
            TiXmlElement *root = doc.RootElement();//goes to completeAccount
    
                    for(TiXmlElement* example2 = root->FirstChildElement(); example2;
                    example2 = example2->NextSiblingElement()) {   //goes to account        
      TiXmlElement* level2  = example2->FirstChildElement();  //goes to the level where name is          
                cout << "\n Name: ";
                cout << example2->FirstChild("name")->FirstChild()->Value();//take child name and turn in to string so i can use cout on it
                cout << "\n type:";
                cout << example2->FirstChild("type")->FirstChild()->Value();
                cout << '\n';
                break;//I used break to get out of the look because when it tired to keep going to read virtualUser It gave me an error.
    
            }
            cout << "Break ";   
             for(TiXmlElement* example2 = root->FirstChildElement(); example2;
                    example2 = example2->NextSiblingElement()) {
                cout << "\n Login Name: ";
                cout << example2->FirstChild("loginName")->FirstChild()->Value();
                    }
        }
    }
    My xml looks like this:
    Name:  Untitled.png
Views: 1374
Size:  9.3 KB

    Optional: My other question is for example I noticed i get an error if one of my account doesn't have "type" in it how would i get it to just put "null" instead of giving me an error?
    Last edited by airesore; 10-27-2011 at 04:51 PM.

  2. #2
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    NextSiblingElement() should do the trick.

    It should be noted that using attributes in tinyxml xml is much simpler than using actual child elements.

    Code:
    <completeAccount>
       <accountEntry>
           <account name = "AAA" type = "admin"/>
           <virtualUser loginName = "BBB" password = "1"/>
       </accountEntry>
    </completeAccount>
    Code:
    struct AccountEntry
    {
       std::string accountName;
       std::string accountType;
       std::string loginName;
       std::string password;
    };
    
    typedef std::vector<AccountEntry> entries;
    entries accountEntries;
    
    std::ostringstream ostrm;
    std::ifstream inFile("myxml.xml");
    ostrm << inFile.rdbuf();
    
    TiXmlDocument doc;
    doc.Parse(ostrm.str().c_str());
    
    inFile.close();
    
    TiXmlElement *pRoot = doc.RootElement();
    if (pRoot)
    {
        AccountEntry entry;
        TiXmlElement *pChild = pRoot->FirstChildElement();
    
        while (pChild)
        {
            TiXmlElement *pChildNode = pChild->FirstChildElement();
             if (pChildNode)
             {
                entry.accountName = pChildNode->Attribute("name");
                entry.accountType = pChildNode->Attribute("type");
             }
    
             pChildNode = pChildNode->NextSiblingElement();
             if (pChildNode)
             {
                entry.loginName = pChildNode->Attribute("loginName");
                entry.password = pChildNode->Attribute("password");
             }
    
             accountEntries.push_back(entry);   
             pChild = pChild->NextSiblingElement();
        }
    }
    That change in the XML will allow you to read in the items in a while loop and it makes the XML simpler to read. This code is not all that safe from a tinyxml standpoint b/c it assumes it knows the layout of the xml file. There are other functions to use which require you to specify the name of the node you want and also provided error checking if that node does not exist. The methods I used will simply throw exceptions deep in xstring or assembly code and will not give you an indication of the problem.

    This code was tested in MSVS 2005 and should work with the example XML.
    Last edited by VirtualAce; 10-27-2011 at 06:28 PM.

  3. #3
    Registered User
    Join Date
    Sep 2011
    Posts
    38
    Thanks for the attempt. However, I'm not allowed to change my XML file though. If anyone could help me get from layer 3 back to layer 2 it would be nice. Because if i use break and try to go back in i'll be back in the first element (account) and not the second (virtual user).

    also how would i do error checking for if the element doesn't exist?

  4. #4
    Registered User
    Join Date
    Sep 2011
    Posts
    38
    ok, I manage to get to the <virtualuser> now. I just need to get to the <random>. I tired using

    Code:
    for(TiXmlElement* example2 = root->FirstChildElement(); example2;
                    example2 = example2->NextSiblingElement("virtualUser")) {
                        TiXmlElement* level2  = example2->FirstChildElement();
                        example2 = example2->NextSiblingElement();// goes to <loginname>
                        cout << "\n Login Name: ";
                        cout << example2->FirstChild("loginName")->FirstChild()->Value();
                        TiXmlElement* level3  = example2->FirstChildElement(); //I thought it would go to <password>, but it didn't
                        example2 = example2->NextSiblingElement(); //I thought it would go to <random>, but it didn't
                        cout << example2->FirstChild("random")->FirstChild()->Value();
                    }
    but it failed. Please help me

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. TinyXML reading XML and storing to string array
    By airesore in forum C++ Programming
    Replies: 9
    Last Post: 10-27-2011, 11:57 AM
  2. problem with loading tinyXML
    By airesore in forum C++ Programming
    Replies: 9
    Last Post: 10-08-2011, 11:58 AM
  3. tinyxml & C++
    By bobthebullet990 in forum C++ Programming
    Replies: 3
    Last Post: 05-04-2006, 03:48 PM
  4. TinyXML - copy subtrees
    By pixsta in forum C++ Programming
    Replies: 1
    Last Post: 01-30-2006, 02:23 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21