質問

my XML knowledge is enough to get by.

What I want to do is blindly parse an XML string and get all of the elements and attributes starting at the root. I can't use recursion like the example in the documentation and I can't seem to grasp how to do it with a loop. I know enough to get the root from the XML string and can loop through the string, but can't seem to get the attributes or text values.

I do not know any names of any tags and need to figure them out as I parse. Anyone have any idea how I start or an example?

Thanks

Here is the code I have so far for a XML string like this, works unless its nested elements like the location and country:

    string strData = "<MyStuff mystring1=""111"" mystring2=""223"">\
                      <MYTAG1>0</MYTAG1>\
                      <MYTAG2>0</MYTAG3>\
                      <MYTAG4>0</MYTAG4>\
                      <location><country>GreatBritain</country></location>\
                      </MyStuff>";

void parseXmlString2( TiXmlNode* root )
{
TiXmlNode*         child;
TiXmlElement*      elem = (TiXmlElement*)root;
TiXmlAttribute*  pAttrib = elem->FirstAttribute();

//This gets the root and its attributes.
while(pAttrib)
{
    cout << "Value: " << pAttrib->Name() << ":" << pAttrib->Value() << endl;
    pAttrib=pAttrib->Next();
}

//Now I want to parse up the rest.
//Does not work if nested such as <location><country>GreatBritain</country></location>
for( child = root->FirstChild(); child; child = child->NextSibling() )
{

    //Test For child.
    if(child->FirstChild())
    {
        //My helper fuct to tell type
        //getType(child->FirstChild()->Type());
        TiXmlNode*         myChild;
        for( myChild = child->FirstChild(); myChild; myChild = child->IterateChildren(child->FirstChild()))
        {
            cout << " " << myChild->Value() << endl;

        }

    }
}

}

役に立ちましたか?

解決

Ultimately this worked for me, thanks to everyone for the input:

for( child = root->FirstChild(); child; child = child->NextSibling() )
{

    if(child->Type() == TiXmlNode::TINYXML_ELEMENT)
    {

        thevalue = child->Value();
    }

    //If this Node has children traverse them.
    //and keep going for all.
    if(child->FirstChild())
    {
        TiXmlNode*  myChild  = child->FirstChild();
        while(myChild)
        {


            if(myChild->Type() == TiXmlNode::TINYXML_ELEMENT)
            {

                thevalue = child->Value();
            }

            if(myChild->Type() == TiXmlNode::TINYXML_TEXT)
            {

                thevalue= myChild->Value();
            }
            myChild  = myChild->FirstChild();
        }
    }
}

他のヒント

I don't know if I got you right. But if you already achieved looping through the XMLElements of your document without recursion then looping through the XMLAttributes should be easy.

Say you have your XMLElement* elem you want to obtain the attributes from simply do

XMLAttribute* attrib;
for( attrib = elem->FirstAttribute(); attrib != NULL; attrib = attrib->Next() ) {
    // do something
    std::cout << attrib->Name() << " " << attrib->Value();
}

Just to see if TinyXML2 does everything right I wrote the following primitive, recursive function which prints out all elements and their attributes (without values):

void printAllChildren( XMLElement* parent, int recursionlvl ) {
    std::stringstream indent("");
    for( int i = 0; i <= recursionlvl; i++ ) {
        indent << " ";
    }

    std::cout << "Element Name: " << indent.str() << parent->Name() << " ";
    const XMLAttribute* attrib;
    for( attrib = parent->FirstAttribute(); attrib != NULL; attrib = attrib->Next() ) {
        std::cout << attrib->Name() << " ";
    }
    std::cout << std::endl;

    XMLElement* childEl;
    for( childEl = parent->FirstChildElement(); childEl != NULL; childEl = childEl->NextSiblingElement() ) {
        printAllChildren( childEl, recursionlvl + 1 );
    }
}

Hope that helps. Cheers.

EDIT: Without the applications actual output it's hard to guess where the error lies. But shouldn't it be

for( myChild = child->FirstChild(); myChild; myChild = child->IterateChildren( child ) )

in your most inner loop? (see a TinyXML Reference)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top