【问题标题】:Boost C++ XML parsing提升 C++ XML 解析
【发布时间】:2014-09-10 13:00:01
【问题描述】:

如果 XML 最多包含 3 个级别,我对如何使用 boost 解析 XML 有点熟悉。但是,我在使用以下示例时遇到了问题:

(请忽略 XML 中稍微缺乏逻辑的地方,因为这是对我无法更改的内容的改编。结构很重要)

<content>

      <Room>
           <RoomName>Livingroom</RoomName>             
            <Description> 
                 <Color>Red</Color>
                 <Size>Small</Size>                   
            </Description>
            <Description>
                 <Color>Blue</Color>
                 <Size>Big</Size>                         
            </Description>         
      </Room>

      <Room>
           <RoomName>Bathroom</RoomName>
            <Description>
                <Color>Green</Color>
                <Size>Medium</Size>
            </Description>
      </Room>  

</content>

我试过这个:

struct Room
{
    std::string roomName;
    std::string  roomColor;
    std::string  roomSize;   
};

void parseRoomsXml(){

    boost::property_tree::ptree tree;
    boost::property_tree::read_xml("./Rooms.xml", tree);
    boost::property_tree::ptree formats = tree.get_child("content");

    BOOST_FOREACH( boost::property_tree::ptree::value_type const& f, formats ) {
        if( f.first == "Room" ) {
            Room s;
            s.roomName = f.second.get<std::string>("RoomName");
            std::cout<<s.roomName<<std::endl;

            const boost::property_tree::ptree & attributes = formats.get_child("Room");

            BOOST_FOREACH( boost::property_tree::ptree::value_type const& v, attributes ) {
                if (v.first == "Description"){
                    s.roomColor = v.second.get<std::string>("Color");
                    s.roomSize = v.second.get<std::string>("Size");
                    std::cout<< s.roomColor << " " <<s.roomSize;
                }
            }
        }
    }
}

结果是第一个房间解析正确,但第二个房间有第一个房间的描述:

===========================

输出:

客厅

红色小号

蓝色大

浴室

红色小号

蓝色大

==========================

预期结果是:

客厅

红色小号

蓝色大

浴室

绿色介质

====================================

在此先感谢,任何帮助将不胜感激,因为我正在努力适应提升。

【问题讨论】:

  • 问题似乎出在这个语句中: const boost::property_tree::ptree & attributes = formats.get_child("Room");它每次都会得到第一个孩子..
  • 它是,我不知道如何操纵它来循环它们

标签: c++ xml boost tree


【解决方案1】:

问题似乎出在这个语句中: const boost::property_tree::ptree & attributes = formats.get_child("Room");

您可以使用以下代码遍历子代:

BOOST_FOREACH(boost::property_tree::ptree::value_type &v,
    config.get_child("path.to.array_of_objects"))
{
    std::cout << "First data: " << v.first.data() << std::endl;
    boost::property_tree::ptree subtree = (boost::property_tree::ptree) v.second ;
    BOOST_FOREACH(boost::property_tree::ptree::value_type &vs,
        subtree)
    {
        std::cout << "Sub data: " << vs.first.data() << std::endl;
        color = vs.second.get<std::string>("Color");
        roomSize = vs.second.get<std::string>("Size");
    }
}

【讨论】:

  • 通过这个实现,返回的子数据是“描述”。我的问题是更深一层,以获取实际的“颜色”和“大小”。当然,如果我使用 vs.second.data(),则不会返回/显示任何内容。这就是为什么我试图让孩子的孩子,所以我可以访问最后一个级别。
  • 在获取颜色和 roomSize 之前使用额外条件,以检查 vs.first.data == "Description"
  • 感谢您的帮助!
【解决方案2】:

这段代码对我来说很好用

boost::property_tree::ptree formats = tree.get_child("content");
BOOST_FOREACH( boost::property_tree::ptree::value_type const& f, formats ) {
if( f.first == "Room" ) {
   Room s;
   s.roomName = f.second.get<std::string>("RoomName");
   boost::property_tree::ptree subtree2 = (boost::property_tree::ptree) f.second ;
   std::cout<<s.roomName<<std::endl;
   BOOST_FOREACH(boost::property_tree::ptree::value_type &v,
           subtree2)
   {

       if(v.first == "Description"){
           s.roomColor = v.second.get<std::string>("Color");
           s.roomSize = v.second.get<std::string>("Size");
           std::cout<< s.roomColor << std::endl<<s.roomSize<<std::endl;

           }
       }
     }
}

【讨论】:

    猜你喜欢
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 2010-10-07
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多