Boost Ptree operation XML, easy and useful

Source: Internet
Author: User
Tags comments ini xml parser

XML format verification
Before the official start, you'd better write down this URL that automatically checks whether the XML format is legal: http://tool.oschina.net/codeformat/xml Click to open the link

Because the configuration file with the wrong format will cause the program to crash, I don't seem to find this library will release an exception, so this kind of format verification is still left to the tool.

XML format introduction

Another one that introduces the XML format, you'd better take a look: http://wenku.baidu.com/link?url=3_sPWvTNPCjq8Q0Udjo-HKQ3lGDoyuY6vc8Z00cyMJgm4ludoT_Ry7LQA9CfFyYeWDOLxMqO_uH16DZ_e3DTic6 open link


Boost ptree

This class can parse and manipulate xml files. The following program enumerates and displays the common operations of the ptree class on the xml file.

get<type>(path) Get the attributes or text content of the node on the path, etc.

For example: Read a single value under a fixed path

Get the text content: pt.get<string>("confi.theme");//<theme>this is the result</theme>

Get the text content of the current node: pt.get<string>();//<theme>this is the result</theme>, if and only when the current node is theme

Get the content of the comment: pt.get<string("conf.<xmlcomment>");//<conf><!-- this is the result --></conf>

Get the attribute content: pt.get<long>("conf.theme.<xmlattr>.id");//<theme id="123456"></theme>,id is 123456

Configuration file


<root>
    <students>
        <name>zhang san</name>
        <age>23</age>
    </students>
</root>


code


#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>

using namespace std;
using namespace boost::property_tree;

int main()
{
	ptree pt;
	//open xml and read information to pt
	read_xml("conf.xml", pt);
	//read value to val need a path 
	string name = pt.get<string>("root.students.name");
	cout<<"name:"<<name<<endl;
	int age =pt.get<int>("root.students.age");
	cout<<"age:"<<age<<endl;
	return 0;
}


Output name: zhang san
age:23
Please press any key to continue...
Traverse single-layer children
When the iterator traverses to a node that is neither an attribute node <xmlattr> nor a comment node <xmlcomment>, it is a child node at this time, and the operation of the child node can be operated in accordance with: "read a single value under a fixed path" . To traverse the children use: auto child = pt.get_child("conf.urls");//Get the child nodes of urls, where the children include not only the attributes of urls, but also the comments of urls, and multiple child nodes in urls< url>www.baidu.com</url><url>www.sina.com</url>, when the child is a url node, the first of the iterator is the name of the node url, second is the ptree structure, you can continue Use the get<type>() method to get the attribute value, comment value, text value, or child value of the url.

Configuration file



<span style="font-size:14px;"><root>
    <students>
        <name>Zhang San</name>
        <name>Li Si</name>
	<name>Wang Er</name>
    </students>
</root></span>


code


<span style="font-size:14px;">#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>

using namespace std;
using namespace boost::property_tree;

int main()
{
	ptree pt;
	//open xml and read information to pt
	read_xml("conf.xml", pt);
	//iter all child value
	auto child = pt.get_child("root.students");
	for (auto i = child.begin();i!=child.end();++i)
	{
		string name = i->second.get_value<string>();//此时i->first的值为路径名:name
		cout<<name<<endl;
	}
	
	return 0;
}</span>


Output
Zhang San
Li Si
King Two
Please press any key to continue... Traverse the child configuration file that contains attributes


<root>
    <student name="zhangsan" age="22">first student</student>
    <student name="lisi" age="23">second student</student>
    <student name="wanger" age="24">third student</student>
</root>


code


#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <iostream>

using namespace std;
using namespace boost::property_tree;

int main()
{
	ptree pt;
	//open xml and read information to pt
	read_xml("conf.xml", pt);
	//iter all child value
	auto child = pt.get_child("root");
	for (auto i = child.begin();i!=child.end();++i)
	{
		string stu= i->second.get<string>("");
		cout<<"student:"<<stu<<endl;
		string  name = i->second.get<string>("<xmlattr>.name");
		cout<<"name:"<<name<<endl;
		string  age = i->second.get<string>("<xmlattr>.age");
		cout<<"age:"<<age<<endl;
	}
	return 0;
}


Output student: first student
name:Zhang San
age:22
student:second student
name:Li Si
age:23
student:third student
name:Wang Er
age:24
Please press any key to continue... Nested Traversal Reposted from: http://www.verydemo.com/demo_c441_i198847.html Category: Network Security / Tool Use / Article
Summary:

property_tree is an attribute data structure that stores multiple attribute values. The attributes of any node can be accessed in a simple way similar to a path, and each node can traverse the child nodes in a style similar to STL. property_tree is particularly suitable for application configuration data processing, and can parse text data in four formats: xml, ini, json and info.

When dealing with files in the four formats, except for some differences when including header files, reading files, and writing files, the other operations on the internal data of the file are basically the same (because the file format is basically the same). In fact, what property_tree uses internally is a small and fast open source XML parser—rapidxml.


Instructions:

1) Different: (XXX code xml, json, ini, info respectively)

View text copy to clipboard print? #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/XXX_parser.hpp> using namespace boost::property_tree; void main(void) {ptree pt; read_XXX("./ test.XXX", pt); // Read file // .... Other operations write_XXX(cout, pt); // Write file, there are two formats: // void write_XXX(const string &, Ptree &pt); // void write_XXX(basic_ostream &, Ptree &pt);}


#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/XXX_parser.hpp>
using namespace boost::property_tree;
void main(void)
{
ptree pt;
read_XXX("./test.XXX", pt); // read file
// .... Other operations
write_XXX(cout, pt); // There are two formats for writing files:
// void write_XXX(const string &, Ptree &pt);
// void write_XXX(basic_ostream &, Ptree &pt);
}


2) Same: (The following is a detailed introduction based on xml, the other three types have not been tested, 囧~)

Test XML file: test.xml

View text copy to clipboard print?


<?xml version="1.0" encoding="utf-8"?>

<config> 
  <file title="windows" size="10Mb"> 
    <!-- File Fisrt Comment -->  
    <!-- File Second Comment -->  
    <paths attr="directory1"> 
      <!-- Paths Comment -->  
      <pathname title="123">abc</pathname>  
      <pathname title="456">efg</pathname>  
      <pathname title="789">hij</pathname> 
    </paths>  
    <paths attr="directory2"> 
      <pathname title="111">klm<!-- pathname Comment -->  
      </pathname>  
      <pathname title="222">nop</pathname>  
      <pathname title="333">qrs</pathname> 
    </paths> 
  </file> 
</config>
code



#include <iostream>
#include <string>
#include <boost/typeof/typeof.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

using namespace std;
using namespace boost::property_tree;

int main(void)
{
    char szXmlFile[] = "./test.xml";

    string strTmp;

    ptree pt;
    xml_parser::read_xml(szXmlFile, pt);

    BOOST_AUTO(file_childs, pt.get_child("config.file"));
    //serch(child,0);
    for (BOOST_AUTO(file_childs_iter, file_childs.begin()); file_childs_iter != file_childs.end(); ++file_childs_iter)//file
    {
        strTmp.clear();
        if ("<xmlattr>" == file_childs_iter->first)
        {
            //The first of this node is xmlattr, when the second node is pair, take the value according to key and value, and key is the path
            strTmp = file_childs_iter->second.get<string>("title"); // Output: windows
            cout<<file_childs_iter->first<<", title: "<<strTmp<<"\n";

            strTmp = file_childs_iter->second.get<string>("size"); // Output: 10Mb
            cout<<file_childs_iter->first<<", size: "<<strTmp<<"\n";

            strTmp = file_childs_iter->second.get<string>("not exits", "This is default");
            cout<<file_childs_iter->first<<", not exist:"<<strTmp<<endl; // Output: This is default
        }
        else if ("<xmlcomment>" == file_childs_iter->first)
        {
            strTmp = file_childs_iter->second.get_value<string>(); // First output: File First Comment
            cout<<file_childs_iter->first<<", comment: "<<strTmp<<"\n"; // Second output: File Second Comment
        }
        else//paths
        {
            BOOST_AUTO(paths_childs, file_childs_iter->second.get_child(""));
            for (BOOST_AUTO(paths_childs_iter, paths_childs.begin()); paths_childs_iter != paths_childs.end(); ++paths_childs_iter)//paths
            {
                strTmp.clear();
                if ("<xmlattr>" == paths_childs_iter->first)
                {
                    cout<<file_childs_iter->first<<" ";
                    //The first of this node is xmlattr, when the second node is pair, take the value according to key and value, and key is the path
                    strTmp = paths_childs_iter->second.get<string>("attr");
                    cout<<paths_childs_iter->first<<", attr: "<<strTmp<<"\n";
                }
                else if ("<xmlcomment>" == paths_childs_iter->first)
                {
                    cout<<file_childs_iter->first<<" ";
                    strTmp = paths_childs_iter->second.get_value<string>();
                    cout<<paths_childs_iter->first<<", comment: "<<strTmp<<"\n";
                }
                else//pathname
                {
                        cout<<file_childs_iter->first<<" ";
                        strTmp = paths_childs_iter->second.get<string>("<xmlattr>.title");
                        cout<<paths_childs_iter->first<<" title: "<<strTmp<<" content:" <<paths_childs_iter->second.data()<<"\n";
                }
            }
        }

    }
    cin.get();
    return 0;
}


Analysis: It can be seen from the above test that the RapidXml open source library encapsulated by BOOST parses the content of the XML file into a tree structure. For example, the node "config.file" used in this example has five child nodes: one attribute child node, two comment child nodes, and two data child nodes, and the order is attribute→comment→data.
①Attribute child node:
Each node has only one attribute child node, which is a one-to-many relationship, that is, one attribute child node corresponds to multiple attributes.
"if ("<xmlattr>" == pos->first)", and then get the value of the attribute as "pos->second.get<string>("title")" and "pos->second.get<string >("size")". Note that the attribute obtained here is no longer "<xmlattr>.title", because at this time pos has already pointed to this node, and it is no longer necessary to use "<xmlattr>" to recurse to the attribute child node.
②Annotation child node: A node can have multiple attribute child nodes, which is a one-to-one relationship. . .
"If ("<xmlcomment>" == pos->first)", "pos->second.data()" to get the attribute; or iter->second.get_value<string>()
③Data sub-node: This kind of node can be regarded as a node again. The following will correspond to attribute sub-nodes, annotation sub-nodes, and data sub-nodes. But note that "pos->second.get_child("")" returns all child nodes (including attributes, comments, data) of the current node, and "pt.get_child("config.file")" returns all the child nodes under the file node Node (including attributes, comments, data).


 


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.