【问题标题】:C++ Boost Property Tree Update Existing Node By Attribute QualifierC ++ Boost属性树按属性限定符更新现有节点
【发布时间】:2011-12-15 02:29:08
【问题描述】:

好的,下面是 XML 结构的示例:

<config>
  <Ignored>
    <Ignore name="Test A">
       <Criteria>
          <value>actual value</value>
       </Criteria>
    </Ignore>
    <Ignore name="Test B">
       <Criteria>
          <value>actual value</value>
       </Criteria>
    </Ignore>
  </Ignored>
<config>

我希望能够做两件事:

  1. 直接对 Test A 元素执行 get 操作,而无需循环所有 Ignore 元素。就像属性上的选择器一样。
  2. 如果不出意外,我需要一种更新任一 Ignore 元素的方法,但似乎无法弄清楚

我必须删除元素并重新创建它吗?我似乎无法找到一种方法来执行通过属性(在该级别将是唯一的)限定元素(在同一级别上有许多具有相同名称的元素)的放置。

类似:

pt.put("config.Ignored.Ignore.<xmlattr>.name='Test A'.Criteria.value",some_var)

或任何其他可以实现最终目标的东西。非常感谢!

全面披露:我对 C++ 还很陌生,可能会遗漏一些明显的东西。

【问题讨论】:

  • 您为此使用 boost 属性树有充分的理由吗?使用真正的 XML 库可能会更好。
  • 诚实吗?不,不能说我有充分的理由。我碰巧得到了提升,并想我会尝试使用那里的东西,而且效果很好......直到解决这个问题。如果要推荐一个真正的 XML 库,会是什么?
  • 我推荐 tinyxml 和 libxml2(取决于您的其他需求)。

标签: c++ boost-propertytree


【解决方案1】:

Boost.property_tree xml 解析器 (RapidXML) 不支持这个。
如果您想要开箱即用的功能,请考虑使用 TinyXPath 之类的东西。

或使用显式循环查找具有所需属性的Ignore 节点。然后你可以使用

someIgnoreNode.put("Criteria.value", some_var);

【讨论】:

  • 谢谢。这就是我发布问题时试图做的事情,我想我错过了一些东西。 BOOST_FOREACH(const ptree::value_type &amp;v2, pt.get_child("config.Ignored")) { if(_stricmp( cText, v2.second.get("&lt;xmlattr&gt;.name","").c_str() ) == 0 ) { BOOST_FOREACH(const ptree::value_type &amp;v3, v2.second) { if(v3.first == "Criteria"){ v3.second.put("value", szValue); } } } 但我得到了这个错误:cannot convert 'this' pointer from 'const boost::property_tree::basic_ptree&lt;Key,Data&gt;' to 'boost::property_tree::basic_ptree&lt;Key,Data&gt; &amp;' 就像我说的,这可能是一些愚蠢的事情。
  • @CapersL,您正在尝试修改 const 对象 - 从 v3v2 类型中删除 const
  • 你看,我知道这将是一件非常愚蠢的事情!正如我所说,我只是一个使用示例 sn-ps 的 C++ n00b,并不真正了解他们在做什么。非常感谢!
【解决方案2】:

您可以使用如下方法:

auto & pt_child = pt.getchild("config.Ignored");
BOOST_FOREACH(ptree::value_type &v1, pt_child)
{
    if (v1.first == Ignore && v1.second.get<std::string>("<xmlattr>.name") == "Test A")
    {
        ptree & ptGrandChild = v1.second;
        ptGrandChild.put<std::string>("Criteria.value", some_var);
    }
}

boost::property_tree::xml_writer_settings<std::string> settings = 
boost::property_tree::xml_writer_make_settings<std::string>('\t', 1);
write_xml(xmlPath, pt, std::locale(), settings);

 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-20
    • 2012-03-02
    相关资源
    最近更新 更多