2014-11-22 72 views
2

下面的代碼試圖從一個XML文件中獲取數據,並將其添加到自定義SensorConfiguration類,然後添加到地圖這些SensorConfigurations的加速XML - 獲取下一個節點

我的問題是,它總是需要第二個foreach循環中的第一個傳感器配置。 我知道爲什麼,但我不知道正確的語法,我不知道如何谷歌。

這裏的XML:

<?xml version="1.0" encoding="utf-8"?> 
<root> 
<sensorconfigurations> 
    <configuration> 
     <name>SensorConfiguration1</name> 
     <sensorid>1</sensorid> 
     <signalindex>1</signalindex> 
     <mappingscheme>mappingscheme1</mappingscheme> 
     <soundpack>test1.wav</soundpack> 
    </configuration> 
    <configuration> 
     <name>SensorConfiguration2</name> 
     <sensorid>2</sensorid> 
     <signalindex>2</signalindex> 
     <mappingscheme>mappingscheme1</mappingscheme> 
     <soundpack>test2.wav</soundpack> 
    </configuration> 
    <configuration> 
     <name>SensorConfiguration3</name> 
     <sensorid>3</sensorid> 
     <signalindex>3</signalindex> 
     <mappingscheme>mappingscheme2</mappingscheme> 
     <soundpack>test3.wav</soundpack> 
    </configuration> 
</sensorconfigurations> 
</root> 

這裏就是整個函數的構造法:

SensorConfigurationBank::SensorConfigurationBank() 
{ 
string m_level; 
using boost::property_tree::ptree; 
ptree pt; 
read_xml("SensorConfigurationBank.xml", pt); 
BOOST_FOREACH(ptree::value_type &v, 
    pt.get_child("root.sensorconfigurations")) 
{ 
    SensorConfiguration newSensorConf; 
    BOOST_FOREACH(ptree::value_type &w, 
     pt.get_child("root.sensorconfigurations.configuration")) 
    { 
     if(w.first == "name") 
     { 
      newSensorConf.setName(w.second.data()); 
     } 
     if(w.first == "sensorid") 
     { 
      string stringToInt = w.second.data(); 
      istringstream iss(stringToInt); 
      int value; 
      iss >> value; 
      newSensorConf.setSensorID(value); 
     } 
     if(w.first == "signalindex") 
     { 
      string stringToInt = w.second.data(); 
      istringstream iss(stringToInt); 
      int value; 
      iss >> value; 
      newSensorConf.setSignalIndex(value); 
     } 
     if(w.first == "mappingscheme") 
     { 
      newSensorConf.setMappingScheme(getMappingScheme(w.second.data())); 
     } 
     if(w.first == "soundpack") 
     { 
      newSensorConf.setSoundPack(w.second.data()); 
     } 
    } 
    sensorConfigurations_.insert(make_pair(newSensorConf.getName(), newSensorConf)); 
} 
//save(); 
} 

我知道這是稍微難以理解,但這裏的重要組成部分:

BOOST_FOREACH(ptree::value_type &w, 
     pt.get_child("root.sensorconfigurations.configuration")) 

相反爲了獲得特定的孩子的'配置',我想讓它找到那個孩子第一個循環正在尋找,所以它看起來在配置#2而不是配置#1達到無限次。

它基本上只是我上面粘貼的代碼的最後一行,需要以某種方式進行修改,然後我認爲它會起作用!提前致謝。

回答

1
  • get_child獲取具有指定節點名稱的單個樹。你似乎期望它返回所有匹配的節點。這根本不是那麼回事。

  • foreach重複的值,你根本沒有使用v。變化:

    if (v.first == "configuration") 
        { 
         // use v.second, which is the subtree 
    
  • 點的路徑是相對的,所以不要用 「root.sensorconfigurations」 所有的時間開始:

    BOOST_FOREACH(ptree::value_type & v, pt.get_child("root.sensorconfigurations")) { 
    
        if (v.first == "configuration") 
        { 
         SensorConfiguration newSensorConf; 
    
         BOOST_FOREACH(ptree::value_type & w, v.second) { 
          if (w.first == "name") { 
           newSensorConf.setName(w.second.data()); 
          } 
    

看到它Live On Coliru

#include <iostream> 
#include <string> 
#include <map> 

#include <boost/foreach.hpp> 
#include <boost/strong_typedef.hpp> 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 
#include <boost/lexical_cast.hpp> 

struct SensorConfiguration { 
    void setName(std::string const& v) { _name = v; } 
    std::string getName() const { return _name; } 
    void setMappingScheme(std::string) {} 
    void setSoundPack(std::string) {} 
    void setSensorID(int) {} 
    void setSignalIndex(int) {} 

    std::string _name; 
}; 

struct MyDemo { 

    MyDemo() { 
     std::string m_level; 
     using boost::property_tree::ptree; 
     ptree pt; 
     read_xml("SensorConfigurationBank.xml", pt); 
     BOOST_FOREACH(ptree::value_type & v, pt.get_child("root.sensorconfigurations")) { 

      if (v.first == "configuration") 
      { 
       SensorConfiguration newSensorConf; 

       BOOST_FOREACH(ptree::value_type & w, v.second) { 
        if (w.first == "name") { 
         newSensorConf.setName(w.second.data()); 
        } 
        if (w.first == "sensorid") { 
         std::string stringToInt = w.second.data(); 
         std::istringstream iss(stringToInt); 
         int value; 
         iss >> value; 
         newSensorConf.setSensorID(value); 
        } 
        if (w.first == "signalindex") { 
         std::string stringToInt = w.second.data(); 
         std::istringstream iss(stringToInt); 
         int value; 
         iss >> value; 
         newSensorConf.setSignalIndex(value); 
        } 
        if (w.first == "mappingscheme") { 
         newSensorConf.setMappingScheme(getMappingScheme(w.second.data())); 
        } 
        if (w.first == "soundpack") { 
         newSensorConf.setSoundPack(w.second.data()); 
        } 
       } 
       sensorConfigurations_.insert(make_pair(newSensorConf.getName(), newSensorConf)); 
      } 
     } 
     // save(); 

    } 

    std::map<std::string, SensorConfiguration> sensorConfigurations_; 

    template <typename T> 
     std::string getMappingScheme(T const& v) { 
      std::cout << __PRETTY_FUNCTION__ << "\n"; 
      return boost::lexical_cast<std::string>(v); 
     } 

}; 

int main() { 
    MyDemo demo; 

    for(auto & e : demo.sensorConfigurations_) 
     std::cout << e.first << "\n"; 
} 
+0

啊,我所需要的只是語法'v.second'而不是pt.get_child。謝謝! – 2014-11-22 16:30:12