mNo edit summary Tags: Visual edit apiedit |
(Removed C++11) Tags: Visual edit apiedit |
||
Line 8: | Line 8: | ||
// loads a level, the given filename could be "maps/level_1.xml" |
// loads a level, the given filename could be "maps/level_1.xml" |
||
− | level::level(std::string level_filename)<br>{<br> pugi::xml_document doc;<br> pugi::xml_parse_result result=doc.load_file(("Data/"+level_filename).c_str());<br> if(!result)<br> {<br> std::cout<<"XML parsed with errors, attr value: ["<<doc.child("node").attribute("attr").value()<<"]\n";<br> std::cout<<"Error description: "<<result.description()<<"\n";<br> std::cout<<"Error offset: "<<result.offset<<" (error at [..."<<(result.offset)<<"]\n\n";<br> }<br><br> for( |
+ | level::level(std::string level_filename)<br>{<br> pugi::xml_document doc;<br> pugi::xml_parse_result result=doc.load_file(("Data/"+level_filename).c_str());<br> if(!result)<br> {<br> std::cout<<"XML parsed with errors, attr value: ["<<doc.child("node").attribute("attr").value()<<"]\n";<br> std::cout<<"Error description: "<<result.description()<<"\n";<br> std::cout<<"Error offset: "<<result.offset<<" (error at [..."<<(result.offset)<<"]\n\n";<br> }<br><br> for(pugi::xml_node_iterator it=doc.children().begin();it!=doc.children().end();it++)<br> |
+ | { |
||
⚫ | |||
+ | pugi::xml_node& c=*it;<br> for(pugi::xml_node_iterator it=c.children().begin();it!=c.children().end();it++)<br> |
||
+ | { |
||
+ | pugi::xml_node& child=*it; <br><br> std::string name(child.name()); |
||
+ | if(name=="flag")<br> {<br> float pos_x=0;<br> float pos_y=0;<br> float pos_z=0;<br><br> for(pugi::xml_attribute_iterator it=child.attributes().begin();it!=child.attributes().end();it++)<br> |
||
+ | {<br> |
||
+ | pugi::xml_attribute& attr=*it; |
||
⚫ | <br> if(std::string(attr.name())=="pos_x")<br> pos_x=std::stof(std::string(attr.value()));<br> else if(std::string(attr.name())=="pos_y")<br> pos_y=std::stof(std::string(attr.value()));<br> else if(std::string(attr.name())=="pos_z")<br> pos_z=std::stof(std::string(attr.value()));<br> }<br> // flag_positions is a std::vector<Urho3D::Vector3><br> flag_positions.emplace_back(pos_x,pos_y,pos_z);<br> } |
||
else if(name=="sound")<br> { |
else if(name=="sound")<br> { |
||
− | // sound_name is a Urho3D::String<br> for(pugi:: |
+ | // sound_name is a Urho3D::String<br> for(pugi::xml_attribute_iterator it=child.attributes().begin();it!=child.attributes().end();it++)<br> |
+ | {<br> |
||
+ | pugi::xml_attribute& attr=*it; |
||
+ | <br> if(std::string(attr.name())=="name")<br> sound_name=attr.value(); |
||
+ | }<br> } |
||
...<br> }<br> }<br>} |
...<br> }<br> }<br>} |
||
'''Note:''' std::stof converts a std::string to a float, there is also stoi for string -> int. |
'''Note:''' std::stof converts a std::string to a float, there is also stoi for string -> int. |
Revision as of 10:55, 7 March 2016
Urho3D uses PugiXML (http://pugixml.org/) and offers wrapping objects for that. I used PugiXML here directly because I used it before and the interface is already quite good and is relatively good documented. Maybe Urho's wrapper has some advantages, maybe not.
Parsing a XML file like this (a map file for USP):
<xml>
<static_model name="Data/Models/level_1" pos_x="0" pos_y="0" pos_z="-10" />
<player pos_x="4" pos_y="10" pos_z="-5" />
<flag pos_x="20.35" pos_y="14" pos_z="-47.6" />
<flag pos_x="-9.9" pos_y="14" pos_z="-47.7" />
<torch pos_x="-244" pos_y="36.2" pos_z="-104" />
<torch pos_x="-199" pos_y="28" pos_z="-138" />
<sound name="Music/Drums of the Deep.ogg" />
</xml>
Can be done like this:
#include <Urho3D/ThirdParty/PugiXml/pugixml.hpp> ... // loads a level, the given filename could be "maps/level_1.xml" level::level(std::string level_filename)
{
pugi::xml_document doc;
pugi::xml_parse_result result=doc.load_file(("Data/"+level_filename).c_str());
if(!result)
{
std::cout<<"XML parsed with errors, attr value: ["<<doc.child("node").attribute("attr").value()<<"]\n";
std::cout<<"Error description: "<<result.description()<<"\n";
std::cout<<"Error offset: "<<result.offset<<" (error at [..."<<(result.offset)<<"]\n\n";
}
for(pugi::xml_node_iterator it=doc.children().begin();it!=doc.children().end();it++)
{ pugi::xml_node& c=*it;
for(pugi::xml_node_iterator it=c.children().begin();it!=c.children().end();it++)
{ pugi::xml_node& child=*it;
std::string name(child.name()); if(name=="flag")
{
float pos_x=0;
float pos_y=0;
float pos_z=0;
for(pugi::xml_attribute_iterator it=child.attributes().begin();it!=child.attributes().end();it++)
{
pugi::xml_attribute& attr=*it;
if(std::string(attr.name())=="pos_x")
pos_x=std::stof(std::string(attr.value()));
else if(std::string(attr.name())=="pos_y")
pos_y=std::stof(std::string(attr.value()));
else if(std::string(attr.name())=="pos_z")
pos_z=std::stof(std::string(attr.value()));
}
// flag_positions is a std::vector<Urho3D::Vector3>
flag_positions.emplace_back(pos_x,pos_y,pos_z);
} else if(name=="sound")
{ // sound_name is a Urho3D::String
for(pugi::xml_attribute_iterator it=child.attributes().begin();it!=child.attributes().end();it++)
{
pugi::xml_attribute& attr=*it;
if(std::string(attr.name())=="name")
sound_name=attr.value(); }
} ...
}
}
}
Note: std::stof converts a std::string to a float, there is also stoi for string -> int.
Handy Print Function
This recursive function uses PugiXML to print everything in an XML file in a nice tree-ish view with indentation:
void xml_print(const pugi::xml_node& n,int depth) { std::string name(n.name()); if(name!="") { for(int i=0;i<depth;i++) std::cout<<" "; std::cout<<"name: "<<name<<endl; } std::string value(n.value()); if(value!="") { for(int i=0;i<depth;i++) std::cout<<" "; std::cout<<"value: "<<value<<endl; } for(pugi::xml_attribute& attr:n.attributes()) { for(int i=0;i<depth;i++) std::cout<<" "; std::cout<<"attribute '"<<attr.name()<<"': '"<<attr.value()<<"'"<<std::endl; } for(pugi::xml_node& child:n.children()) { for(int i=0;i<depth;i++) std::cout<<" "; std::cout<<"child"<<std::endl; xml_print(child,depth+1); } }
Usage:
pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file("test.xml"); if(!result) { std::cout<<"XML parsed with errors, attr value: ["<<doc.child("node").attribute("attr").value()<<"]\n"; std::cout<<"Error description: "<<result.description()<<"\n"; std::cout<<"Error offset: "<<result.offset<<" (error at [..."<<(result.offset)<<"]\n\n"; return; } for(auto& c:doc.children()) xml_print(c,0);
Example output (from a totally different but more complex XML file):
name: rdf:RDF attribute 'xmlns:foaf': 'http://xmlns.com/foaf/0.1/' attribute 'xmlns:rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' attribute 'xmlns:ussec': 'http://www.rdfabout.com/rdf/schema/ussec/' attribute 'xmlns:corp': 'http://xmlns.com/foaf/corp#' child name: corp:Company attribute 'rdf:about': 'http://www.rdfabout.com/rdf/usgov/sec/id/cik0000037996' child name: ussec:tradingSymbol child value: F child name: foaf:name child value: FORD MOTOR CO child name: ussec:tenPercentOwnerOf attribute 'rdf:resource': 'http://www.rdfabout.com/rdf/usgov/sec/id/cik0001075056' attribute 'foaf:name': 'VASTERA INC' child name: ussec:cik child value: 0000037996