青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

C++分析研究  
C++
日歷
<2025年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
統(tǒng)計(jì)
  • 隨筆 - 92
  • 文章 - 4
  • 評(píng)論 - 4
  • 引用 - 0

導(dǎo)航

常用鏈接

留言簿

隨筆檔案

文章檔案

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

 

  boost.property_tree可以用來解析xml和json文件,我主要用它來解析xml文件,它內(nèi)部封裝了號(hào)稱最快的xml解析器rapid_xml,其解析效率還是很好的。但是在使用過程中卻發(fā)現(xiàn)各種不好用,歸納一下不好用的地方有這些:

  獲取不存在的節(jié)點(diǎn)時(shí)就拋出異常

  獲取屬性值時(shí),要排除屬性和注釋節(jié)點(diǎn),如果沒注意這一點(diǎn)就會(huì)拋出異常,讓人摸不著頭腦。

  內(nèi)存模型有點(diǎn)怪。

  默認(rèn)不支持中文的解析。解析中文會(huì)亂碼。

  ptree獲取子節(jié)點(diǎn)

  獲取子節(jié)點(diǎn)接口原型為get_child(node_path),這個(gè)node_path從當(dāng)前路徑開始的全路徑,父路徑和子路徑之間通過“.”連接,如“root.sub.child”。需要注意的是get_child獲取的是第一個(gè)子節(jié)點(diǎn),如果我們要獲取子節(jié)點(diǎn)列表,則要用路徑“root.sub”,這個(gè)路徑可以獲取child的列表。如果獲取節(jié)點(diǎn)的路徑不存在則會(huì)拋出異常,這時(shí),如果不希望拋出異常則可以用get_xxx_optional接口,該接口返回一個(gè)optional的結(jié)果出來,由外面判斷是否獲取到結(jié)果托福答案 www.jamo123.com

  //ptree的optional接口

  auto item = root.get_child_optional("Root.Scenes");

  該接口返回的是一個(gè)optional,外面還要判斷該節(jié)點(diǎn)是否存在,optional對(duì)象通過bool操作符來判斷該對(duì)象是否是無效值,通過指針訪問

  符"*"來訪問該對(duì)象的實(shí)際內(nèi)容。建議用optional接口訪問xml節(jié)點(diǎn)。

  //ptree的optional接口

  auto item = root.get_child_optional("Root.Scenes");

  if(item)

  cout<<"該節(jié)點(diǎn)存在"<

  ptree的內(nèi)存模型

  ptree維護(hù)了一個(gè)pair的子節(jié)點(diǎn)列表,first指向的是該節(jié)點(diǎn)的TagName,second指向的才是ptree節(jié)點(diǎn),因此在遍歷ptree子節(jié)點(diǎn)時(shí)要注意迭代器的含義。

  for (auto& data : root)

  {

  for (auto& item : data.second) //列表元素為pair,要用second繼續(xù)遍歷

  {

  cout<

  }

  }

  需要注意的是ptree.first可能是屬性("")也可能是注釋(""),只有非注釋類型的節(jié)點(diǎn)才能使用獲取屬性值、子節(jié)點(diǎn)等常用接口。

  ptree獲取屬性值

  通過get(attr_name)可以獲取屬性的值,如果想獲取屬性的整形值的話,可以用get("Id"),返回一個(gè)整數(shù)值。有一點(diǎn)要注意如果ptree.first為""時(shí),是沒有屬性值的,可以通過data()來獲取注釋內(nèi)容。如果這個(gè)ptree.first不為時(shí)需要在屬性名稱前面加".",即get(".Id")才能正確獲取屬性值。可以看到獲取屬性值還是比較繁瑣的,在后面要介紹的幫助類中可以簡(jiǎn)化屬性值的獲取。如果要獲取節(jié)點(diǎn)的值則用get_value()接口,該接口用來獲取節(jié)點(diǎn)的值,如節(jié)點(diǎn):2通過get_value()就可以獲取值"2"。

  解析中文的問題

  ptree只能解析窄字符的xml文件,如果xml文件中含有unicode如中文字符,解析出來就是亂碼。解析unicode要用wptree,該類的接口均支持寬字符并且接口和ptree保持一致。要支持中文解析僅僅wptree還不夠,還需要一個(gè)unicode轉(zhuǎn)換器的幫助,該轉(zhuǎn)換器可以實(shí)現(xiàn)寬字符和窄字符的轉(zhuǎn)換,寬窄的互相轉(zhuǎn)換函數(shù)有很多實(shí)現(xiàn),不過c++11中有更簡(jiǎn)單統(tǒng)一的方式實(shí)現(xiàn)寬窄字符的轉(zhuǎn)換。

  c++11中寬窄字符的轉(zhuǎn)換:

  std::wstring_convert> conv

  (newstd::codecvt("CHS"));

  //寬字符轉(zhuǎn)為窄字符

  string str = conv.to_bytes(L"你好");

  //窄字符轉(zhuǎn)為寬字符

  string wstr = conv.from_bytes(str);

  boost.property_tree在解析含中文的xml文件時(shí),需要先將該文件轉(zhuǎn)換一下。

  boost解決方法:

  #include "boost/program_options/detail/utf8_codecvt_facet.hpp"

  void ParseChn()

  {

  std::wifstream f(fileName);

  std::locale utf8Locale(std::locale(), new boost::program_options::detail::utf8_codecvt_facet());

  f.imbue(utf8Locale); //先轉(zhuǎn)換一下

  //用wptree去解析

  property_tree::wptree ptree;

  property_tree::read_xml(f, ptree);

  }

  這種方法有個(gè)缺點(diǎn)就是要引入boost的libboost_program_options庫,該庫有二十多M,僅僅是為了解決一個(gè)中文問題,卻要搞得這么麻煩,有點(diǎn)得不償失。好在c++11提供更簡(jiǎn)單的方式,用c++11可以這樣:

  void Init(const wstring& fileName, wptree& ptree)

  {

  std::wifstream f(fileName);

  std::locale utf8Locale(std::locale(), new std::codecvt_utf8);

  f.imbue(utf8Locale); //先轉(zhuǎn)換一下

  //用wptree去解析

  property_tree::read_xml(f, ptree);

  }

  用c++11就不需要再引入boost的libboost_program_options庫了,很簡(jiǎn)單。

  property_tree的幫助類

  property_tree的幫助類解決了前面提到的問題:

  用c++11解決中文解析問題

  簡(jiǎn)化屬性的獲取

  增加一些操作接口,比如一些查找接口

  避免拋出異常,全部返回optional對(duì)象

  隔離了底層繁瑣的操作接口,提供統(tǒng)一、簡(jiǎn)潔的高層接口,使用更加方便。

  下面來看看這個(gè)幫助類是如何實(shí)現(xiàn)的吧:

  #include

  #include

  using namespace boost;

  using namespace boost::property_tree;

  #include

  #include

  #include

  #include

  using namespace std;

  const wstring XMLATTR = L"";

  const wstring XMLCOMMENT = L"";

  const wstring XMLATTR_DOT = L".";

  const wstring XMLCOMMENT_DOT = L".";

  class ConfigParser

  {

  public:

  ConfigParser() : m_conv(new code_type("CHS"))

  {

  }

  ~ConfigParser()

  {

  }

  void Init(const wstring& fileName, wptree& ptree)

  {

  std::wifstream f(fileName);

  std::locale utf8Locale(std::locale(), new std::codecvt_utf8);

  f.imbue(utf8Locale); //先轉(zhuǎn)換一下

  wcout.imbue(std::locale("chs")); //初始化cout為中文輸出格式

  //用wptree去解析

  property_tree::read_xml(f, ptree);

  }

  // convert UTF-8 string to wstring

  std::wstring to_wstr(const std::string& str)

  {

  return m_conv.from_bytes(str);

  }

  // convert wstring to UTF-8 string

  std::string to_str(const std::wstring& str)

  {

  return m_conv.to_bytes(str);

  }

  //獲取子節(jié)點(diǎn)列表

  auto Descendants(const wptree& root, const wstring& key)->decltype(root.get_child_optional(key))

  {

  return root.get_child_optional(key);

  }

  //根據(jù)子節(jié)點(diǎn)屬性獲取子節(jié)點(diǎn)列表

  template

  vector GetChildsByAttr(const wptree& parant, const wstring& tagName, const wstring& attrName, const T& attrVal)

  {

  vector v;

  for (auto& child : parant)

  {

  if (child.first != tagName)

  continue;

  auto attr = Attribute(child, attrName);

  if (attr&&*attr == attrVal)

  v.push_back(child.second);

  }

  return v;

  }

  //獲取節(jié)點(diǎn)的某個(gè)屬性值

  template

  optional Attribute(const wptree& node, const wstring& attrName)

  {

  return node.get_optional(XMLATTR_DOT + attrName);

  }

  //獲取節(jié)點(diǎn)的某個(gè)屬性值,默認(rèn)為string

  optional Attribute(const wptree& node, const wstring& attrName)

  {

  return Attribute(node, attrName);

  }

  //獲取value_type的某個(gè)屬性值

  template

  optional Attribute(const wptree::value_type& pair, const wstring& attrName)

  {

  if (pair.first == XMLATTR)

  return pair.second.get_optional(attrName);

  else if (pair.first == XMLCOMMENT)

  return optional();

  else

  return pair.second.get_optional(XMLATTR_DOT + attrName);

  }

  //獲取value_type的某個(gè)屬性值,默認(rèn)為string

  optional Attribute(const wptree::value_type& pair, const wstring& attrName)

  {

  return Attribute(pair, attrName);

  }

  //根據(jù)某個(gè)屬性生成一個(gè)的multimap

  template>

  multimap MakeMapByAttr(const wptree& root, const wstring& key, const wstring& attrName, F predict = [](wstring& str){return true; })

  {

  multimap resultMap;

  auto list = Descendants(root, key);

  if (!list)

  return resultMap;

  for (auto& item : *list)

  {

  auto attr = Attribute(item, attrName);

  if (attr&&predict(*attr))

  resultMap.insert(std::make_pair(*attr, item.second));

  }

  return resultMap;

  }

  private:

  using code_type = std::codecvt;

  std::wstring_convert m_conv;

  };

  View Code

  測(cè)試文件test.xml和測(cè)試代碼:

  void Test()

  {

  wptree pt; pt.get_value()

  ConfigParser parser;

  parser.Init(L"test1.xml", pt); //解決中文問題,要轉(zhuǎn)換為unicode解析

  auto scenes = parser.Descendants(pt, L"Root.Scenes"); //返回的是optional

  if (!scenes)

  return;

  for (auto& scene : *scenes)

  {

  auto s = parser.Attribute(scene, L"Name"); //獲取Name屬性,返回的是optional

  if (s)

  {

  wcout << *s << endl;

  }

  auto dataList = parser.Descendants(scene.second, L"DataSource"); //獲取第一個(gè)子節(jié)點(diǎn)

  if (!dataList)

  continue;

  for (auto& data : *dataList)

  {

  for (auto& item : data.second)

  {

  auto id = parser.Attribute(item, L"Id");

  auto fileName = parser.Attribute(item, L"FileName");

  if (id)

  {

  wcout << *id << L" " << *fileName << endl; //打印id和filename

  }

  }

  }

  }

  }

  測(cè)試結(jié)果:


  可以看到通過幫助類,無需使用原生接口就可以很方便的實(shí)現(xiàn)節(jié)點(diǎn)的訪問與操作。使用者不必關(guān)注內(nèi)部細(xì)節(jié),根據(jù)統(tǒng)一而簡(jiǎn)潔的接口就可以操作xml文件了。

  一點(diǎn)題外話,基于這個(gè)幫助類再結(jié)合linq to object可以輕松的實(shí)現(xiàn)linq to xml:

  //獲取子節(jié)點(diǎn)SubNode的屬性ID的值為0x10000D的項(xiàng)并打印出該項(xiàng)的Type屬性

  from(node.Descendants("Root.SubNode")).where([](XNode& node)

  {

  auto s = node.Attribute("ID");

  return s&&*s == "0x10000D";

  }).for_each([](XNode& node)

  {

  auto s = node.Attribute("Type");

  if (s)

  cout << *s << endl;

  });

posted on 2014-03-11 16:27 HAOSOLA 閱讀(5158) 評(píng)論(0)  編輯 收藏 引用

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


 
Copyright © HAOSOLA Powered by: 博客園 模板提供:滬江博客
PK10開獎(jiǎng) PK10開獎(jiǎng)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美中文在线观看| 欧美成年人网站| 尤物yw午夜国产精品视频| 女生裸体视频一区二区三区| 猫咪成人在线观看| 亚洲最新在线视频| 亚洲一区二区三区在线| 国产一区二区三区四区hd| 亚洲成色777777女色窝| 亚洲国产精品悠悠久久琪琪| 欧美日韩成人激情| 性色一区二区| 久久久久久久久久久久久女国产乱| 91久久中文字幕| 一本色道久久加勒比88综合| 国产日韩欧美在线看| 欧美成人精品高清在线播放| 欧美色视频在线| 久久精品青青大伊人av| 免费一级欧美在线大片| 亚洲一区影院| 久久九九国产精品| 一本色道婷婷久久欧美| 香港成人在线视频| 亚洲理伦电影| 亚洲欧美一区二区三区在线| 亚洲激情一区| 亚洲一区欧美激情| 亚洲人成网站色ww在线| 亚洲在线视频| 最新亚洲激情| 亚洲欧美日韩一区在线观看| 亚洲欧洲一区二区天堂久久 | 免费影视亚洲| 亚洲欧美另类在线观看| 浪潮色综合久久天堂| 亚洲在线黄色| 久热综合在线亚洲精品| 亚洲主播在线观看| 美女脱光内衣内裤视频久久影院| 亚洲一区二区三区在线看 | 蜜桃久久精品乱码一区二区| 亚洲欧美国产不卡| 男人的天堂亚洲在线| 亚洲一区二区三区精品在线| 久久琪琪电影院| 亚洲欧美视频一区| 欧美极品在线播放| 久久亚洲精品网站| 欧美亚男人的天堂| 欧美黑人在线观看| 国产色综合天天综合网| 亚洲毛片在线| 亚洲成色www久久网站| 亚洲欧美日韩在线播放| 99riav1国产精品视频| 久久久久高清| 欧美在线视频一区二区| 欧美日韩极品在线观看一区| 欧美/亚洲一区| 国产日韩欧美中文| 一区二区三区|亚洲午夜| 亚洲日韩视频| 久久久久国内| 久久精品在这里| 国产精品午夜视频| 亚洲精品资源美女情侣酒店| 亚洲国产91色在线| 欧美一区二区在线视频| 亚洲在线视频免费观看| 欧美激情综合在线| 欧美暴力喷水在线| 激情五月综合色婷婷一区二区| 亚洲女女女同性video| 在线视频你懂得一区| 欧美aa国产视频| 美女福利精品视频| 国内精品视频久久| 亚洲欧美综合精品久久成人 | 欧美日韩在线看| 亚洲欧洲一级| 亚洲精品乱码久久久久久黑人| 久久蜜桃资源一区二区老牛| 久久亚洲一区| 国产在线播精品第三| 午夜精品久久久久久久久久久久| 亚洲资源av| 欧美日韩亚洲免费| 亚洲精品一区二区三区福利| 亚洲精品国产视频| 欧美成人午夜激情视频| 欧美黄在线观看| 亚洲韩国日本中文字幕| 快播亚洲色图| 欧美成人综合| 亚洲激情视频在线观看| 欧美成人小视频| 欧美激情第六页| 亚洲欧洲一区二区在线观看 | 久久aⅴ国产紧身牛仔裤| 国产精品亚发布| 亚洲欧美999| 久久er99精品| 国产一区在线免费观看| 久久er99精品| 美女久久一区| 亚洲国产精品精华液网站| 毛片基地黄久久久久久天堂| 欧美激情中文字幕一区二区| 亚洲精品久久久蜜桃| 欧美激情一区二区三区不卡| 亚洲日韩欧美视频一区| 亚洲无人区一区| 国产精品久久久久久久7电影| 亚洲午夜精品网| 性欧美xxxx视频在线观看| 国产欧美一区二区三区沐欲| 欧美呦呦网站| 欧美顶级大胆免费视频| 亚洲人成网站色ww在线 | 亚洲欧洲精品一区二区| 一区二区三区成人精品| 国产精品免费福利| 欧美一进一出视频| 男人的天堂亚洲| 亚洲免费观看在线观看| 欧美图区在线视频| 午夜电影亚洲| 麻豆精品视频在线观看| 亚洲精品国产品国语在线app| 欧美日韩另类一区| 亚洲欧美色一区| 免费成人在线视频网站| 亚洲精品在线观看视频| 国产精品成人国产乱一区| 欧美一区二区在线视频| 欧美激情亚洲视频| 亚洲性线免费观看视频成熟| 国产欧美三级| 久热爱精品视频线路一| 日韩视频不卡| 久久成人在线| 亚洲日本va午夜在线电影| 欧美午夜剧场| 久久精品最新地址| 亚洲欧洲美洲综合色网| 欧美一级片在线播放| 在线看视频不卡| 欧美日韩免费视频| 欧美亚洲综合另类| 亚洲国产另类精品专区| 亚洲在线中文字幕| 精品96久久久久久中文字幕无| 欧美精品网站| 欧美亚洲视频| 91久久精品一区二区三区| 午夜精品在线看| 亚洲高清在线精品| 国产精品久久久久三级| 久久免费视频一区| 一级日韩一区在线观看| 麻豆精品网站| 亚洲免费在线精品一区| 在线精品一区| 国产精品激情偷乱一区二区∴| 久久久91精品国产| 一区二区日韩伦理片| 欧美91福利在线观看| 亚洲欧美在线一区| 亚洲欧洲一区二区在线观看 | 亚洲日本视频| 久久先锋资源| 亚洲男女自偷自拍| 亚洲国产精品一区二区久| 国产精品嫩草99av在线| 欧美~级网站不卡| 性欧美超级视频| 亚洲精选视频在线| 免费看av成人| 欧美一区二区三区精品电影| 国产精品电影网站| 蜜乳av另类精品一区二区| 午夜国产精品视频| 日韩视频在线一区二区三区| 男女激情久久| 久久久久国产一区二区三区四区 | 欧美在线日韩| 一区二区三区免费观看| 欧美激情一区二区三区高清视频| 久久av一区| 亚洲欧美电影在线观看| 亚洲精选一区二区| 永久555www成人免费| 国产麻豆日韩| 国产精品igao视频网网址不卡日韩| 欧美成人激情在线| 久久免费的精品国产v∧| 欧美一级视频免费在线观看| 亚洲色诱最新| 亚洲美女视频在线免费观看|