xml — Как использовать атрибут в качестве ключевого слова поиска с TinyXML2 (C ++)

Я пытаюсь использовать атрибут в качестве ключевого слова, чтобы найти элемент, который я хочу.
это может работать, но только когда это первый элемент.

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>

0

Решение

Вам нужно перебрать все элементы ip, проверяя атрибут ip3, пока не найдете нужный. Но вот простой способ сделать это, используя мое расширение tinyxml2 :

#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;
}
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 inputif(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?
}
0

По вопросам рекламы [email protected]