XML解析

XML解析,通常可以有几种选择:

   1: Tinyxml
   2: boost::property_tree

 

根据tag, text, attribute的不同,可以将XML简单分成以下几种情况:

 

场景1

<calendar>
    <Monday>
        <weather>Rainy</weather>
    </Monday>
    <Tuesday>
        <weather>Rainy</weather>
    </Tuesday>
    <Wednesday>
        <weather>Sunny</weather>
    </Wednesday>
    <Thursday>
        <weather>Cloudy</weather>
    </Thursday>
</calendar>

在这种场景下,所有节点都没有attribute信息,而且在同一层次下的所有tag都是不相同的,比如Monday和Tuesday就是同一层次下不相同的两tag。

由于tag不相同,就保证了一条从root开始的tag路径只能索引到一条text信息。

这是最简单的应用场景,可以使用boost::property_tree的

std::string weather = tree.get<std::string>("calendar.Monday");

直接获取到text信息。

 

场景2

   1: <calendar>
   2:     <days>
   3:         <day name="Monday">
   4:             <weather>Rainy</weather>
   5:         </day>
   6:         <day name="Tuesday">
   7:             <weather>Rainy</weather>
   8:         </day>
   9:         <day name="Wednesday">
  10:             <weather>Sunny</weather>
  11:         </day>
  12:         <day name="Thursday">
  13:             <weather>Cloudy</weather>
  14:         </day>
  15:     </days>
  16: </calendar>

在这种场景下,同一层次下的各个子节点拥有相同的tag名称,用于区别各个节点的方法在于它们有一个相同名称的attribute,通过attribute的值来互相区分。

 

这种情况下,使用boost::property_tree就不那么容易操作了。

 

Why?

因为boost::property_tree是为了下面的场景http://www.boost.org/doc/libs/1_41_0/doc/html/property_tree.html

   1: struct ptree
   2: {
   3:    data_type data;                         // data associated with the node
   4:    list< pair<key_type, ptree> > children; // ordered list of named children
   5: };

而设计的,这里的data相当于text,因此boost::property_tree没有显式地支持attribute,attribute也被作为一个child放在了children数组中。

因此要使用下面的代码

   1: BOOST_FOREACH(boost::property_tree::ptree::value_type &day,    
   2:     root.get_child("calendar.days"))
   3: {
   4:     if (boost::iequals(day.first, "day"))
   5:     {
   6:         std::string attrVal = day.second.get<std::string>("<xmlattr>.name");
   7:         if (boost::iequals(attrVal, "Monday"))
   8:         {
   9:             std::string weather = day.second.get_child("weather").get_value<std::string>();
  10:         }
  11:     }
  12: }

 

但是这种场景下,用TinyXml就方便多了,因为TinyXml可以支持attribute。

posted @ 2014-01-26 16:43  Daniel King  阅读(218)  评论(0编辑  收藏  举报