How to Access Data in a Property Tree

Posted 用代码创造价值

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了How to Access Data in a Property Tree相关的知识,希望对你有一定的参考价值。

在属性树里怎么访问数据?

属性树类似于(几乎是)一个标准容器,其值类型为pair。它具有通常的成员函数,如insert、push_back、find、erase等,当然可以使用这些函数来填充和访问树。例如,下面的代码添加了关键词为“pi”的数据(几乎)等于数学pi值:

  1. ptree pt;
  2. pt.push_back(ptree::value_type("pi", ptree("3.14159")));
为了求出pi的值,我们可以这样做:
  1. ptree::const_iterator it = pt.find("pi");
  2. double pi = boost::lexical_cast<double>(it->second.data());
这里也要提示下:这里使用了一个非常好用的扩展类型转化,convert的库的函数:lexical_cast

这看起来很麻烦,如果pi值不存储在树顶附近,我们会更关心错误。幸运的是,还有另一种正确的方法:
  1. ptree pt;
  2. pt.put("pi", 3.14159); // put double
  3. double pi = pt.get<double>("pi"); // get double
没有比这更简单的了。基本上,有2个家庭成员函数,get和put,这允许直观地访问存储在树中的数据(直接的孩子或不是)。


三种方式获取数据


get有三个版本:get、get(默认值版本)和get_optional,这与失败处理策略不同。所有版本都使用路径说明符,它决定了在哪个键中搜索值。它可以是单个键,也可以是键的路径,其中路径元素以特殊字符(.)分隔。(如果没有具体说明)。例如debug.logging.errorlevel 可能是一个带点作为分隔符的有效路径。

1.抛出异常的处理
  1. ptree pt;
  2. /* ... */
  3. float v = pt.get<float>("a.path.to.float.value");

此调用将定位树中的适当节点,并尝试将其数据字符串转换为浮点值。如果失败,则抛出异常。如果路径不存在,它将是ptree_bad_path异常。如果值不能被翻译,它将是ptree_bad_data。它们都源于ptree_error,以使普通处理成为可能。

2.有默认值的版本
  1. ptree pt;
  2. /* ... */
  3. float v = pt.get("a.path.to.float.value", -1.f);
它将执行与上面相同的操作,但是如果失败,它将返回第二个参数指定的默认值(这里-1.f)而不是抛出。这在通常情况下是非常有用的,因为人们想要省略一些键。请注意,在这里通常没有必要的类型规范,因为类型是由默认值参数决定的。

3.可选的版本
  1. ptree pt;
  2. /* ... */
  3. boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value");
这个版本使用boost::optional来处理提取失败。在成功的提取上,它将返回boost::optional的初始化值。否则,它将返回未初始化的boost::optional

要从这棵树(不是一些子键)中检索值,可以使用get_value、get_value (default-value version)和get_value_optional。它们具有相同的语义以获得函数,但它们不接受路径参数。不要调用get和empty路径,因为它将尝试以空名称提取子键的内容。

如果要使用除默认之外的分隔,您需要显式地构造路径对象。
ptree的路径类型是string_path实例化,因此最容易引用它的方法是ptree::path_type。
这样你就可以使用在他们的key上有(.)的树【也就是,key里有点的路径】:
  1. typedef ptree::path_type path;
  2. pt.get<float>(path("p.a.t.h/t.o/v.a.l.u.e", ‘/‘));
  3. pt.get(path("p.a.t.h/t.o/v.a.l.u.e", ‘/‘), 0, NULL);
  4. pt.get_optional<std::string>(path("p.a.t.h/t.o/v.a.l.u.e", ‘/‘));
可以看到,这里使用的是"/"来作为分隔符,原因,很简单,你在key你有了点(.),就不能再使用点来作为分隔了,我们需要使用新的字符!

注意:在PropertyTree的预发布版本中存在的get和get_optional的特殊重载已被删除。这是因为重载与使用每个调用的数据转换器冲突。
    

Two Ways of Putting Data

同样的道理,有获得值,就有添加值!get和put是一对,在添加数据时不需要处理丢失的值。如果提供的值不能转换为树的数据类型,则函数将抛出ptree_bad_data
  1. ptree pt;
  2. pt.put("a.path.to.float.value", 3.14f);
  3. // Overwrites the value
  4. pt.put("a.path.to.float.value", 2.72f);
  5. // Adds a second node with the new value.
  6. pt.add("a.path.to.float.value", 3.14f);

调用put将在指定的路径中插入一个新值,以便调用来指定相同的路径将检索它。
此外,在路径遍历过程中,put将插入任何丢失的路径元素。例如,调用put("key1.key2.key3", 3.14f),在一个空的树上,
将插入三个新子:
key1, 
key1.key2; 
key1.key2.key3。
最后一个将接收到一个字符串“3.14”作为数据,而前两个将会有空的数据字符串。总是在现有序列的后面插入新的键

put和add之间的区别是,put将覆盖现有的值,如果有的话,add将创建一个新的节点来保存该值,即使指定的路径引用了现有的节点
与get_value类似,还有一个put_value函数。它不接受路径:
ptree pt;
pt.put_value(3.14f);






















以上是关于How to Access Data in a Property Tree的主要内容,如果未能解决你的问题,请参考以下文章

How to: Create a Business Model in the XPO Data Model Designer

If application data needs to be sent to IP address xx.xx.xx.xx, how does it work in underneath netwo

python 可打印的pandas组(来自http://stackoverflow.com/questions/14734533/how-to-access-pandas-groupby-datafr

How To Commit Just One Data Block Changes In Oracle Forms

how to use composer in fiddler

OGG How to Resync Tables / Schemas on Different SCN s in a Single Replicat