Reading the tutorial for property_tree, using the functions ptree.find, ptree.get and ptree.get_child, they will only return the topmost node, so if I had two different children nodes under my root named '<Logistics>' with different data within the children, I would only be able to access the first one. So my question is that how would I go about navigating to each top node under my root when they are all named the same? I basicly will have a file that looks something like this: XML file contents: <Technologies> <Logistics ID="Damage Diagnostics"> <DisplayName>Damage Diagnostics</DisplayName> <Cost>1500</Cost> <Description>Increases repair ability by 10%</Description> <RepairAbility>10</RepairAbility> <Requires>Advanced Starship Repair</Requires> <Category>Logistics</Category> <Model>lrgbuilding0</Model> <AIValue>30</AIValue> </Logistics> <Logistics ID="Basic Self-Repair"> /* I need to access this node */ <DisplayName>Basic Self-Repair</DisplayName> <Cost>3000</Cost> <Description>Increases repair ability by 10%</Description> <RepairAbility>10</RepairAbility> <Requires>Damage Diagnostics</Requires> <Category>Logistics</Category> <Model>controlgrav0</Model> <AIValue>40</AIValue> </Logistics> </Technologies> I will have a very large number of nodes with the same name under my root, but each will have different data in their children that I need to access. A full DOM parser is too much overhead when I do not need any validation, but rather I need to read a large number of configuration data across XML files. I really like the ease of use of this library, but I just can't figure this out. Any help would be greatly appreciated.
Demetrius Cassidy wrote:
Reading the tutorial for property_tree, using the functions ptree.find, ptree.get and ptree.get_child, they will only return the topmost node, so if I had two different children nodes under my root named '<Logistics>' with different data within the children, I would only be able to access the first one.
So my question is that how would I go about navigating to each top node under my root when they are all named the same?
[snip]
I basicly will have a file that looks something like this:
XML file contents: <Technologies> <Logistics ID="Damage Diagnostics">
[snip]
</Logistics> <Logistics ID="Basic Self-Repair"> /* I need to access this node */
[snip]
</Logistics> </Technologies>
Well, something along the lines of this should work (caution: not tested): ptree technologies; /* load xml */ for (ptree::const_iterator iter = technologies.begin(); iter != technologies.end(); ++iter) { std::cout << "ID: " << (*iter).get<std::string>("<xmlattr>.ID") << '\n'; } HTH // Johan
"Johan Nilsson" wrote in message news:...
Well, something along the lines of this should work (caution: not tested): ptree technologies; /* load xml */ for (ptree::const_iterator iter = technologies.begin(); iter != technologies.end(); ++iter) { std::cout << "ID: " << (*iter).get<std::string>("<xmlattr>.ID") << '\n' } HTH // Johan
Unfortunally this does not work, *iter returns ptree::value_type, so even if I could do std::cout << "ID: " << (*iter).second.get<std::string>("<xmlattr>.ID") << '\n', it will throw "ptree_bad_path" because it can't find the key. It will also throw with get("Technologies.Logistics") and get_child(...). Even worse is that incrementing my iterator from my root node will cause iter.begin == iter.end, and if I try ptree.find("<xmlattr>.ID") or ptree.find("Technologies.Logistics") it will return an invalid iterator. The only thing that even works is the following code, except it will only print out the topmost node. I need to be able to print out the whole tree and their respective children. BOOST_FOREACH(ptree::value_type &v, pt.get_child("Technologies.Logistics")) print(v.second.data()); <Tech> <Logistics> <somedata>1.0</somedata> </Logistics> /* stops here */ <Logistics> ... Unless someone knows of a similar lightweight XML parser that allows me to iterate through the tree, I would greatly appreciate any help with property_tree.
Demetrius Cassidy wrote:
"Johan Nilsson" wrote in message news:...
Well, something along the lines of this should work (caution: not tested): ptree technologies; /* load xml */ for (ptree::const_iterator iter = technologies.begin(); iter != technologies.end(); ++iter) { std::cout << "ID: " << (*iter).get<std::string>("<xmlattr>.ID") << '\n' } HTH // Johan
Unfortunally this does not work, *iter returns ptree::value_type, so even if I could do std::cout << "ID: " << (*iter).second.get<std::string>("<xmlattr>.ID") << '\n', it will throw "ptree_bad_path" because it can't find the key. It will also throw with get("Technologies.Logistics") and get_child(...).
I said I didn't test it - it required a little tweaking: --- #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <sstream> #include <iostream> using namespace boost::property_tree; std::stringstream data( "<Technologies>" " <Logistics ID=\"Damage Diagnostics\">" " <DisplayName>Damage Diagnostics</DisplayName>" " <Cost>1500</Cost>" " <Description>Increases repair ability by 10%</Description>" " <RepairAbility>10</RepairAbility>" " <Requires>Advanced Starship Repair</Requires>" " <Category>Logistics</Category>" " <Model>lrgbuilding0</Model>" " <AIValue>30</AIValue>" " </Logistics>" " <Logistics ID=\"Basic Self-Repair\">" " <DisplayName>Basic Self-Repair</DisplayName>" " <Cost>3000</Cost>" " <Description>Increases repair ability by 10%</Description>" " <RepairAbility>10</RepairAbility>" " <Requires>Damage Diagnostics</Requires>" " <Category>Logistics</Category>" " <Model>controlgrav0</Model>" " <AIValue>40</AIValue>" " </Logistics>" "</Technologies>"); ptree pt; read_xml(data, pt); ptree technologies = pt.get_child("Technologies"); for (ptree::const_iterator iter = technologies.begin(); iter != technologies.end(); ++iter) { std::string const & name = (*iter).first; ptree const& logistics = (*iter).second; std::cout << name << ": ID = " << logistics.get<std::string>("<xmlattr>.ID") << '\n'; } --- // Johan
participants (2)
-
Demetrius Cassidy
-
Johan Nilsson