c++ - Get SubTag details of Tag [Boost Porperty_tree XML] -


i trying details of "subchapter" tag. not know how information inside tag.

my xml looks this:

<xml>     <chapter>         <name>first chapter</name>         <link>xyz1</link>         <chapter>             <name>first sub-chapter</name>             <link>xyz2</link>         </chapter>     </chapter> </xml> 

now want information of second chapter tag... c++ looks this:

boost::property_tree::ptree pt; boost::property_tree::xml_parser::read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace );  boost_foreach(const boost::property_tree::ptree::value_type& node, pt.get_child("xml")) {     if( node.first == "chapter" )     {         chapter chp;         chp.name = node.second.get<std::string>("name");         chp.link = node.second.get<std::string>("link");          //boost::property_tree::ptree::value_type test = node.second.get<boost::property_tree::ptree::value_type>("chapter");         //chapter chp2;         //chp2.name = test.second.get<std::string>("name");         //chp2.link = test.second.get<std::string>("link");          //chp.sub_chapters.push_back( chp2 );          m_chapters.push_back( chp );     } } 

i tried can see commented lines. tried use boost_foreach. there way reach goal?

thanks help! greetz!

i'd use simple recursive find algorithm:

template <typename tree, typename out> out find_all_chapters(tree const& pt, out out) {     using namespace boost::property_tree;     boost_foreach(typename tree::value_type const& ch, pt) {         if (ch.first == "chapter") {             *out++ = chapter {                      ch.second.template get<std::string>("name"),                     ch.second.template get<std::string>("link")                 };              out = find_all_chapters(ch.second, out);         }     }     return out; } 

this assumes nested chapters appear inside other chapters (otherwise move recursive call out of if() conditional block.)

you can use like

int main() {     boost::property_tree::ptree pt;     boost::property_tree::xml_parser::read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace );      std::vector<chapter> m_chapters;     find_all_chapters(pt.get_child("xml"), back_inserter(m_chapters));      (auto& ch : m_chapters)         std::cout << "chapter '" << ch.name << "', link: '" << ch.link << "'\n"; } 

and prints

chapter 'first chapter', link: 'xyz1' chapter 'first sub-chapter', link: 'xyz2' 

full listing

live on coliru

#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/foreach.hpp> #include <iostream>  struct chapter {     std::string name, link; };  template <typename tree, typename out> out find_all_chapters(tree const& pt, out out) {     using namespace boost::property_tree;     boost_foreach(typename tree::value_type const& ch, pt) {         if (ch.first == "chapter") {             *out++ = chapter {                      ch.second.template get<std::string>("name"),                     ch.second.template get<std::string>("link")                 };              out = find_all_chapters(ch.second, out);         }     }     return out; }  int main() {     boost::property_tree::ptree pt;     boost::property_tree::xml_parser::read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace );      std::vector<chapter> m_chapters;     find_all_chapters(pt.get_child("xml"), back_inserter(m_chapters));      (auto& ch : m_chapters)         std::cout << "chapter '" << ch.name << "', link: '" << ch.link << "'\n"; } 

update

to comments, here's how i'd it:

live on coliru

#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> #include <boost/foreach.hpp> #include <iostream>  struct chapter {     std::string name, link;     std::vector<chapter> sub_chapters; };  void find_all_chapters(boost::property_tree::ptree const& pt, chapter& into) {     for(auto& ch : pt) {         if (ch.first == "chapter") {             into.sub_chapters.push_back({                      ch.second.template get<std::string>("name"),                     ch.second.template get<std::string>("link"),                     {}                 });              find_all_chapters(ch.second, into.sub_chapters.back());         }     } }  void print(chapter const& book_or_chapter, std::string const& indent = "")  {     (auto& ch : book_or_chapter.sub_chapters) {         std::cout << indent << " - chapter '" << ch.name << "', link: '" << ch.link << "'\n";         print(ch, "    " + indent);     } }  int main() {     boost::property_tree::ptree pt;     boost::property_tree::xml_parser::read_xml(std::cin, pt, boost::property_tree::xml_parser::trim_whitespace );      chapter book;     find_all_chapters(pt.get_child("xml"), book);      print(book); } 

with input xml like

<xml>     <chapter>         <name>first chapter</name>         <link>xyz1</link>         <chapter>             <name>first sub-chapter</name>             <link>xyz2</link>             <chapter>                 <name>sub sub</name>                 <link>xyz3</link>                 <chapter>                     <name>sub sub sib</name>                     <link>xyz4</link>                 </chapter>             </chapter>         </chapter>     </chapter>     <chapter>         <name>second chapter</name>         <link>abc1</link>         <chapter>             <name>first sub-chapter</name>             <link>abc2</link>         </chapter>     </chapter> </xml> 

prints

 - chapter 'first chapter', link: 'xyz1'      - chapter 'first sub-chapter', link: 'xyz2'          - chapter 'sub sub', link: 'xyz3'              - chapter 'sub sub sib', link: 'xyz4'  - chapter 'second chapter', link: 'abc1'      - chapter 'first sub-chapter', link: 'abc2' 

Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -