如何使用TinyXML2(C ++)将Attribute作为搜索关键字

时间:2017-09-11 07:53:15

标签: c++ xml xml-attribute tinyxml tinyxml2

我正在尝试使用Attribute作为关键字来查找我想要的元素。 它可以工作,但只有当它是第一个元素。

bool readXML(){
string gateWay_str="",user_Input="";
XMLDocument XML_file;
XML_file.LoadFile("exception_ip.xml");                      //XML file Name
XMLHandle docHandle( &XML_file );                           //XMLHandle
XMLNode* node_ctrl;                                         //Node pointer
XMLElement* gateWay_Ele = docHandle.FirstChildElement("exception_ip").FirstChildElement("ip").ToElement();  //Get Node by XMLHandle and turn to Element 
cout<<"Test ip3=";                                          //show to user 
cin>>user_Input;                                            //user input

if(gateWay_Ele){                                            //is gateWay_Ele null?
    gateWay_str=gateWay_Ele->Name();                        //get Element name and show
    cout<< "Got gateWay_Ele = "<<gateWay_str<<endl;
}
if(gateWay_Ele ->Attribute("ip3",(user_Input.c_str()))){    //find Attribute where ip3 = "user input"
        node_ctrl=gateWay_Ele->FirstChild();                //make node_ctrl point FirstChild
        if(node_ctrl==nullptr){                             //is nullptr?
            cout<<"node_ctrl = nullptr";
            return false;
        }
        else{                                               
            gateWay_Ele=node_ctrl->ToElement();             //turn node_ctel to Element
            gateWay_str = gateWay_Ele->GetText();           //get Text
            cout<<"GateWay = "<<gateWay_str<<endl;          //show
            return true;                                    //return true
        }
    }
return false;

}

我的XML是

<?xml version="1.0" ?> 
<exception_ip>  
	<ip ip3="23">	
      <gateway>123.123.23.1</gateway>
      <dnsp>dnsp23</dnsp>
      <dnss>dnss23</dnss>
	</ip>
	<ip ip3="24">	
      <gateway>123.123.24.1</gateway>
      <dnsp>dnsp24</dnsp>
      <dnss>dnss24</dnss>
	</ip>
</exception_ip>

仅在输入为23

时才有效

我尝试过使用NextSiblingElement(“ip”) 让点继续下一个兄弟元素。 但它只是无限循环

do{
if(gateWay_Ele ->Attribute("ip3",(user_Input.c_str()))){    //find Attribute where ip3 = "user input"
        node_ctrl=gateWay_Ele->FirstChild();                //make node_ctrl point FirstChild
        if(node_ctrl==nullptr){                             //is nullptr?
            cout<<"node_ctrl = nullptr";
            return false;
        }
        else{                                               
            gateWay_Ele=node_ctrl->ToElement();             //turn node_ctel to Element
            gateWay_str = gateWay_Ele->GetText();           //get Text
            cout<<"GateWay = "<<gateWay_str<<endl;          //show
            return true;                                    //return true
        }
    }
else{
    gateWay_Ele->NextSiblingElement("ip");
}
}while(true);

谢谢!

2 个答案:

答案 0 :(得分:0)

你需要遍历所有&#34; ip&#34;元素,测试&#34; ip3&#34;属性,直到找到你想要的那个。但是,使用my tinyxml2 extension

这是一种简单的方法
#include <string>
#include <iostream>
#include <conio.h>  // for _getch()
// include the header for tinyxml2ex which includes tinyxml2, remember to put them on your include path
#include "tixml2ex.h"

using namespace std;

int main()
{
    // put the XML into a string for simplicity
    string testXml{ R"-(
<?xml version="1.0" ?>
<exception_ip>
    <ip ip3="23">
        <gateway>123.123.23.1</gateway>
        <dnsp>dnsp23</dnsp>
        <dnss>dnss23</dnss>
    </ip>
    <ip ip3="24">
        <gateway>123.123.24.1</gateway>
        <dnsp>dnsp24</dnsp>
        <dnss>dnss24</dnss>
    </ip>
</exception_ip>
)-"s };

    auto doc = tinyxml2::load_document (testXml);
    // find the required element by XPath and list its member elements
    if (auto ip = find_element (*doc, "/exception_ip/ip[@ip3='24']"s))
    {
        for (auto e : ip)
            cout << e->Name() << " " << text (e) << endl;
    }
    else
        cout << "could not find ip element" << endl;

   return 0;
}

答案 1 :(得分:0)

我通过另一种方式迭代所有元素并且它可以工作。

bool readXML(){
    string gateway_str="",user_Input="",dnsp_str="",dnss_str="";
    XMLDocument XML_file;
    if(XML_file.LoadFile("exception_ip.xml")){
        cout<<"Can't find exception_ip.xml"<<endl;
        return false;                                                                   //XML file Name
    }
    XMLHandle docHandle( &XML_file );                                                                       //XMLHandle
    XMLNode* node_ctrl = docHandle.FirstChildElement("exception_ip").FirstChildElement("ip").ToNode();
    XMLElement* element_main = node_ctrl->ToElement();

    cout<<"Test ip3=";                                          //show to user
    cin>>user_Input;                                            //user input


    if(element_main){                                           //do if element_main not null
        do{
            element_main = node_ctrl ->ToElement();             //let node turn to element

            if(element_main ->Attribute("ip3",(user_Input.c_str())))    //if Attribute is what we wnat?
            {
                element_main = element_main ->FirstChildElement();      //make element to child

                gateway_str = element_main ->GetText();                         //get test put into str

                element_main = element_main->NextSiblingElement();

                dnsp_str    = element_main->GetText();

                element_main = element_main->NextSiblingElement();

                dnss_str    = element_main->GetText();


                cout<<"ip3="<<user_Input<<endl<<"GW= "<<gateway_str<<endl<<"DNS1= "<<dnsp_str<<endl<<"DNS2= "<<dnss_str<<endl;              //output
                return true;                                            //return 1
            }
            else{                                                       //if Attribute not match
                if(node_ctrl=element_main ->NextSibling()){}            //make pointer to next element (Sibling)
                else{
                    cout<<"Can't find "<<user_Input<<endl;              //Can't find what we want QQ
                    return false;                                       //bye
                }
            }

        }while(true);
    }
    return false;                                                       //total fail -file can't found?
}