2016-08-18 7 views
1

私はいくつかのXMLを操作するためにboost :: property_treeを使用しています。私は、XML文書はとてもようなXML文書にboostプロパティツリーadd_childでパスを指定

をサブノードを追加する必要があります。

<MPD> 
    <Period> 
     <AdaptationSet mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1"> 
      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/> 
      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"> 
       <!-- value already exists here //--> 
       <!-- need to insert new entry here //--> 
      </ContentProtection> 
     </AdaptationSet> 

     <AdaptationSet> 
      <ContentProtection ... /> 
      <ContentProtection ... /> 
      <ContentProtection ... /> 
     </AdaptationSet> 
    </Period> 
</MPD> 

は、だから私は、上記のXMLでマークの場所に新しいエントリを挿入するために、次のコードを持っている:

typedef boost::property_tree::iptree  property_tree_t; 
typedef boost::shared_ptr<property_tree_t> shared_ptree_t; 
typedef boost::optional<property_tree_t &> optional_ptree_t; 

string sSearchSchemeIdUri = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"; 
string sChildName; 

optional_ptree_t spPeriod = spPTree->get_child_optional("MPD.Period"); 
if (spPeriod) 
{ 
    for (auto & adaptSetNextChild : spPeriod->get_child("AdaptationSet")) 
    { 
     sChildName = adaptSetNextChild.first; 

     if (sChildName.compare("ContentProtection") == 0) 
     { 
      property_tree_t & ptContentProtection = adaptSetNextChild.second; 
      string    sSchemeIdUri  = ptContentProtection.get<string>("<xmlattr>.schemeIdUri", ""); 

      if (sSchemeIdUri.compare(sSearchSchemeIdUri) == 0) 
      { 
       property_tree_t ptPssh; 
       ptPssh.clear(); 
       ptPssh.add("cenc:PSSH", sPssh); 
       ptContentProtection.add_child("./", ptPssh); 
      } 
     } 
    } 
} 

上記のコードは次のように追加されたデータをラップ:私はリットルをいただきたい

<></> 
<//></> 

私は避けるべきです。

この誤ったマークアップは、私が「./」として、インサート・パスを指定し、私のadd_child呼び出しから推測来ている

は何も指定しないと、例外が発生し、これは動作します私が見つけた唯一のものです。

は、引数は例えば、現在のパスを指定するにはどのような方法が

/** Add the node at the given path. Create any missing parents. If there 
* already is a node at the path, add another one with the same key. 
* @param path Path to the child. The last fragment must not have an 
*    index. 
* @return A reference to the inserted subtree. 
* @note Because of the way paths work, it is not generally guaranteed 
*  that a node newly created can be accessed using the same path. 
*/ 
self_type &add_child(const path_type &path, const self_type &value); 

ありますされていることを述べてthe header file for ptree.hp pは、読んでました。 ptContentProtectionのパス?

答えて

1

addメンバーの代わりにputメンバーが必要です。

Live On Coliru

#include <boost/property_tree/xml_parser.hpp> 
#include <iostream> 

static std::string const sample = R"(<MPD> 
    <Period> 
     <AdaptationSet mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1"> 
      <ContentProtection schemeIdUri="urn:mpeg:dash:mp4protection:2011" value="cenc"/> 
      <ContentProtection schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95">OLD VALUE</ContentProtection> 
     </AdaptationSet> 

     <AdaptationSet> 
     </AdaptationSet> 
    </Period> 
</MPD>)"; 

static std::string sSearchSchemeIdUri = "urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"; 

int main() { 
    using boost::property_tree::iptree; 
    iptree pt; 
    { 
     std::istringstream iss(sample); 
     read_xml(iss, pt); 
    } 

    for (auto& as : pt.get_child("MPD.Period")) { 
     if (as.first == "AdaptationSet") { 
      for (auto& cp : as.second) { 
       if (cp.first == "ContentProtection" && cp.second.get("<xmlattr>.schemeIdUri", "") == sSearchSchemeIdUri) 
       { 
        cp.second.put_value("NEW VALUE"); 
       } 
      } 
     } 
    } 

    auto xws = boost::property_tree::xml_writer_make_settings<std::string>(' ', 4); 
    write_xml(std::cout, pt, xws); 
} 
+0

を追加しました[ライブデモ](http://coliru.stacked-crooked.com/a/1ae75504e5eb658e:ここ

OLD VALUENEW VALUEとの置き換えサンプルです) – sehe

+0

ありがとうsehe、私はそれを感謝します。 –

関連する問題