boost解析xml文件

前面我们介绍了xml文件,今天我们试着用boost库来解析xml文件。我们将举两个例子来说明怎么使用。

来自boost官方的例子

先看xml文件的内容:

<debug><filename>debug.log</filename><modules><module>Finance</module><module>Admin</module><module>HR</module></modules><level>2</level>
</debug>

我们再来看如何使用boost读取和保存xml文件。

// ----------------------------------------------------------------------------
// Copyright (C) 2002-2006 Marcin Kalicinski
//
// Distributed under the Boost Software License, Version 1.0. 
// (See accompanying file LICENSE_1_0.txt or copy at 
// http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see www.boost.org
// ----------------------------------------------------------------------------#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>struct debug_settings
{std::string m_file;               // log filenameint m_level;                      // debug levelstd::set<std::string> m_modules;  // modules where logging is enabledvoid load(const std::string &filename);void save(const std::string &filename);
};void debug_settings::load(const std::string &filename)
{// Create empty property tree objectusing boost::property_tree::ptree;ptree pt;// Load XML file and put its contents in property tree. // No namespace qualification is needed, because of Koenig // lookup on the second argument. If reading fails, exception// is thrown.read_xml(filename, pt);// Get filename and store it in m_file variable. Note that // we specify a path to the value using notation where keys // are separated with dots (different separator may be used // if keys themselves contain dots). If debug.filename key is // not found, exception is thrown.m_file = pt.get<std::string>("debug.filename");// Get debug level and store it in m_level variable. This is // another version of get method: if debug.level key is not // found, it will return default value (specified by second // parameter) instead of throwing. Type of the value extracted // is determined by type of second parameter, so we can simply // write get(...) instead of get<int>(...).m_level = pt.get("debug.level", 0);// Iterate over debug.modules section and store all found // modules in m_modules set. get_child() function returns a // reference to child at specified path; if there is no such // child, it throws. Property tree iterator can be used in // the same way as standard container iterator. Category // is bidirectional_iterator.//BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules"))//    m_modules.insert(v.second.data());}void debug_settings::save(const std::string &filename)
{// Create empty property tree objectusing boost::property_tree::ptree;ptree pt;// Put log filename in property treept.put("debug.filename", m_file);// Put debug level in property treept.put("debug.level", m_level);// Iterate over modules in set and put them in property// tree. Note that the add function places new key at the// end of list of keys. This is fine in most of the// situations. If you want to place item at some other// place (i.e. at front or somewhere in the middle),// this can be achieved using a combination of the insert// and put_value functionsBOOST_FOREACH(const std::string &name, m_modules)pt.add("debug.modules.module", name);// Write property tree to XML filewrite_xml(filename, pt); //write_xml(cout,pt); //这个函数有重载. 可以用流 也可直接用文件名. }int main()
{try{debug_settings ds;ds.load("debug_settings.xml");ds.save("debug_settings_out.xml");std::cout << "Success\n";}catch (std::exception &e){std::cout << "Error: " << e.what() << "\n";}return 0;
}

解析:

load函数:

首先定义了解析树

using boost::property_tree::ptree;ptree pt;

然后读取xml文件
接下来三行代码,读取文件里的内容。
我们注意到:
上面的xml的根节点是debug。然后有三个节点:filename,modules,level。
其中modules是一个含有子节点的复合节点。
于是:
1.

    m_file = pt.get<std::string>("debug.filename");

读取filename。如读取失败,则抛出异常。
2.

m_level = pt.get("debug.level", 0);

获取level数,当然了我们也可以通过和前一句一样的语法获取m_level:

m_level = pt.get<int>("debug.level");

但是同样这句话一旦获取不到,就会抛出异常,如果我们想获取不到,返回一个默认值0呢?此时可以使用

m_level = pt.get("debug.level", 0);

来实现。其中最后返回值的类型通过默认值来推断,非常类似c++11的auto语法。
3.

BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules"))m_modules.insert(v.second.data());

由于modules是一个复合节点,我们可以通过循环遍历的方法访问节点的子节点。
BOOST_FOREACH类似c++11的for(auto& value: range)
循环遍历的第一句就是:<module>Finance</module>,而v.first==module,v.second==Finance,但是我们要通过data()来获取。
我们可以通过改变上述语句为下面语句验证我的推断:

BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules")){std::cout << v.first<< " "<<v.second.data()<<std::endl;m_modules.insert(v.second.data());}

值得注意的是我测试的时候发现获取first加不加.data()都可以,但获取second必须加.data().

save函数

实际上是read的翻译版,只需将get换成put即可.我们只要按照变量对应的标签加即可。

另一个更复杂的例子

xml文件如下:

<debug name="debugname"><file name="debug.log"/><modules type="internal"><module1>Finance_Internal</module1><module2>Admin_Internal</module2><module3>HR_Internal</module3></modules><modules type="external"><module>Finance_External</module><module>Admin_External</module><module>HR_External</module>  </modules>
</debug>

分析以上xml文件,我们会发现此刻带有了属性,还有深层嵌套。分析起来,稍复杂一些。前面我们讲过xml文件中属性其实可以看成子元素的形式。因此我们对debug遍历的时候,第一句应该是name="debugname",第二句是<file name="debug.log"/>
第三句是:

    <modules type="internal"><module1>Finance_Internal</module1><module2>Admin_Internal</module2><module3>HR_Internal</module3></modules>
 第四句是:   <modules type="external"><module>Finance_External</module><module>Admin_External</module><module>HR_External</module>  </modules>

然后我们看代码:

#include <iostream>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>using namespace std;
using namespace boost::property_tree;int main(void){ptree pt;read_xml("debug_settings2.xml", pt);//loop for every node under debugBOOST_FOREACH(ptree::value_type &v1, pt.get_child("debug")){if (v1.first == "<xmlattr>"){ //it's an attribute//read debug name="debugname"cout << "debug name=" << v1.second.get<string>("name") << endl;}else if (v1.first == "file"){//read file name="debug.log"cout << "  file name=" << v1.second.get<string>("<xmlattr>.name") << endl;}else{ // v1.first == "modules"//get module typecout << "  module type:" << v1.second.get<string>("<xmlattr>.type") << endl;//loop for every node under modulesBOOST_FOREACH(ptree::value_type &v2, v1.second){if (v2.first == "<xmlattr>"){  //it's an attribute//this can also get module typecout << "  module type again:" << v2.second.get<string>("type") << endl;}else{//all the modules have the same structure, so just use data() function.cout << "    module name:" << v2.second.data() << endl;}}//end BOOST_FOREACH}}//end BOOST_FOREACH
}

注意:
对于属性来说,first指”<xmlattr>“,而不是“name”,v.second指的是name的具体值.

参考文献:

1.使用Boost property tree来解析带attribute的xml
2.http://www.boost.org/doc/libs/1_46_1/doc/html/boost_propertytree/tutorial.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/258961.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用网桥模式(bridge networking mode)配置KVM-QUME虚拟机网络

&#xff08;1&#xff09;linux要工作在网桥模式&#xff0c;所以必须安装两个RPM包。即&#xff1a;bridge-utils和tunctl。它们提供所需的brctl、tunctl命令行工具。能够使用yum在线安装&#xff1a; [rootserver3 ~]# yum install bridge-utils &#xff08;2&#xff09;查…

python数据处理常用函数_pandas数据分析常用函数总结大全:上篇

基础知识在数据分析中就像是九阳神功&#xff0c;熟练的掌握&#xff0c;加以运用&#xff0c;就可以练就深厚的内力&#xff0c;成为绝顶高手自然不在话下&#xff01; 为了更好地学习数据分析&#xff0c;我对于数据分析中pandas这一模块里面常用的函数进行了总结。整篇总结&…

XML的应用

1.XML的定义: XML 于 1998 年 2 月 10 日成为 W3C 的推荐标准。xml一般指可扩展标记语言&#xff0c;可扩展标记语言是一种很像超文本标记语言的标记语言。它的设计宗旨是传输数据&#xff0c;而不是显示数据。 2.通过XML我们可以自定义自己的标签&#xff0c;如&#xff1a; &…

虚拟机VMware里 windows server 2003 扩充C盘方法

你会经常用windows server 2003 吗&#xff1f;应该不会吧&#xff0c;有时一些东西必须装在windows server 2003 上才能用&#xff0c;所以 用虚拟机把&#xff0c;好&#xff0c;装在虚拟机上&#xff0c;8G的C盘够你用吗&#xff0c;一个稍微大点的软件就可能就没空间来存储…

从运维角度浅谈MySQL数据库优化

一个成熟的数据库架构并不是一开始设计就具备高可用、高伸缩等特性的&#xff0c;它是随着用户量的增加&#xff0c;基础架构才逐渐完善。这篇博文主要谈MySQL数据库发展周期中所面临的问题及优化方案&#xff0c;暂且抛开前端应用不说&#xff0c;大致分为以下五个阶段&#x…

c语言c99标准_自学C语言之一

上次自学C语言还是在刚开学到国庆期间&#xff0c;听学姐的建议买了本C语言的书&#xff0c;在军训期间的晚上翻翻看看。后来选课、开始正式上课、面试社团、开各种会等等&#xff0c;好像每天都有许多事要忙&#xff0c;但又没忙出来什么结果&#xff0c;慢慢地好像就把C语言放…

boost解析info文件

先给出info文件&#xff1a; parameters {MAX_STAGES 4MAX_DEPTH 3MAX_NUMTRESS 5MAX_NUMTHRESHS 500MAX_NUMFEATS 1000,1000,1000,500,500,500,400,400MAX_RATIO_RADIUS 0.3,0.2,0.2,0.15,0.12,0.10,0.08,0.06,0.06,0.05BAGGING_OVERLAP 0.4IS_FLIP true }meanface {MAX_ITER…

Font Rending 的 Hint 机制对排版的影响

Font Rending 的 Hint 机制对排版的影响【转】 在设计一种 Font 时&#xff0c;设计者使用的是一个抽象的单位&#xff0c;叫做 EM&#xff0c;来源于大写 M 的宽度&#xff08;通常英文字体中大写 M 的宽度最大&#xff09;。EM 即不同于在屏幕显示时用的像素&#xff08;Pixe…

《SQL初学者指南(第2版)》——2.4 指定列

本节书摘来自异步社区出版社《SQL初学者指南&#xff08;第2版&#xff09;》一书中的第2章&#xff0c;第2.4节&#xff0c;作者&#xff1a;【美】Larry Rockoff&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.4 指定列 到目前为止&#xff0c;我们只…

python从文件中提取特定文本_使用Python从HTML文件中提取文本

我发现最好的一段代码用于提取文本&#xff0c;而不需要javascript或不需要的东西&#xff1a;import urllibfrom bs4 import BeautifulSoupurl "http://news.bbc.co.uk/2/hi/health/2284783.stm"html urllib.urlopen(url).read()soup BeautifulSoup(html)# kill …

mutable、volatile的使用

本文转载自http://blog.csdn.net/tht2009/article/details/6920511 (1)mutable 在C中&#xff0c;mutable是为了突破const的限制而设置的。被mutable修饰的变量&#xff0c;将永远处于可变的状态&#xff0c;即使在一个const函数中&#xff0c;甚至结构体变量或者类对象为const…

文本框点击后文字消失总结

1.文本框显示默认文字&#xff1a; <textarea>白鸽男孩</textarea> <textarea>白鸽男孩</textarea>    2.鼠标点击文本框&#xff0c;默认文字消失&#xff1a; <textarea οnfοcus”if(value’白鸽男孩’) {value’ ‘}”>白鸽男孩</text…

[裴礼文数学分析中的典型问题与方法习题参考解答]4.5.8

需要全部的解答, 请 http://www.cnblogs.com/zhangzujin/p/3527416.html 设 $f(x)$ 在 $[a,\infty)$ 上可微; 且 $x\to\infty$ 时, $f(x)$ 单调递增趋于 $\infty$, 则 $$\bex \int_a^\infty \sin f(x)\rd x,\quad \int_a^\infty \cos f(x)\rd x \eex$$ 都收敛. 证明: 由 $$\be…

《PowerShell V3——SQL Server 2012数据库自动化运维权威指南》——2.13 创建视图...

本节书摘来自异步社区出版社《PowerShell V3—SQL Server 2012数据库自动化运维权威指南》一书中的第2章&#xff0c;第2.13节&#xff0c;作者&#xff1a;【加拿大】Donabel Santos&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 2.13 创建视图 本方案展…

python刷抖音_用Python生成抖音字符视频!

抖音字符视频在去年火过一段时间。 反正我是始终忘不了那段极乐净土的音乐... 这一次自己也来实现一波&#xff0c;做一个字符视频出来。 主要用到的库有cv2&#xff0c;pillow库。 原视频如下&#xff0c;直接抖音下载的&#xff0c;妥妥的水印。 不过并不影响本次的操作。 / …

变长参数

转载自&#xff1a;http://blog.csdn.net/tht2009/article/details/7019635 变长参数 设计一个参数个数可变、参数类型不定的函数是可能的&#xff0c;最常见的例子是printf函数、scanf函数和高级语言的Format函数。在C/C中&#xff0c;为了通知编译器函数的参数个数和类型可变…

第十七章 我国农业科学技术

农村改革解说&#xff08;专著&#xff09;第十七章 第十七章 我国农业科学技术 1、为什么说科学技术是生产力&#xff1f; 我们说科学技术是生产力&#xff0c;是因为在构成生产力的两个主要因素中&#xff0c;都包含着科学技术在内。 A、生产力中人的因素是同一定的科学技术紧…

《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一1.2 选购镜头时应注意的事项...

本节书摘来自异步社区出版社《淘宝网开店 拍摄 修图 设计 装修 实战150招》一书中的第1章&#xff0c;第1.2节&#xff0c;作者&#xff1a; 葛存山&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.2 选购镜头时应注意的事项 面对如此之多的镜头&#xf…

OpenCV中的神器Image Watch

Image Watch是在VS2012上使用的一款OpenCV工具&#xff0c;能够实时显示图像和矩阵Mat的内容&#xff0c;跟Matlab很像&#xff0c;方便程序调试&#xff0c;相当好用。跟VS2012配合使用&#xff0c;简直就是一款神器&#xff01;让我一下就爱上它了&#xff01; 下面介绍一些链…

python异步_Python通过Thread实现异步

当long函数耗时较长时&#xff0c;需要程序先向下执行&#xff0c;这就需要异步&#xff0c;改写代码如下&#xff1a; import _thread import time def long(cb): print (long execute) def fun(callback): time.sleep(5) result long end callback(result) _thread.start_ne…