46

我正在尝试编写一个XML解析器,将XML文件解析为boost::property_tree并出现了这个问题。我如何(快速)检查某个属性的子级是否存在?

显然,我可以使用每个增压器-然而,难道没有更好的解决方案吗?

1
  • 虽然这些解决方案似乎可以避免在树上迭代,但请记住,在幕后,它们仍在这样做,因此您的算法可能是n^2…如果您关心性能并有空闲的内存,可以使用映射容器进行快速查找。
    – 富有
    评论 2014年7月23日15:28

5个答案5

重置为默认值
58
optional<const-ptree&>child=node.get_child_optional(“possible_missing_node”);if(!child){//缺少子节点}
  • 为了让你的例子起作用,我不得不删除了“const”,你能解释一下为什么在这里使用“cont”吗?
    – 塞鲁普
    评论 2016年9月14日8:43
  • 为了安全。读取配置时,几乎没有理由修改值。快速搜索显示,ptree仍然有一个get_child_optional重载(在boost 1.61.0中),该重载返回可选的<const ptree&>,因此您的错误将与随后对该值所做的操作有关。 评论 2016年9月19日10:33
  • 1
    我尝试了几种替代方法,最终使用了boost::optional。注意,您还可以使用Boost文档中的代码直接访问数据:请参阅在此处添加文档。请尝试以下操作:boost::optional<float>v=pt.get_optional<float>(“a.path.to.float.value”); 评论 2018年6月11日8:35
25

这里有几个其他选择:

if(node.count(“possibiliy_missing”)==0){...}ptree::constassoc_iterator it=ptree.find(“possible_missing”);if(它==ptree.not_found()){...}
4
  • 我喜欢第二个。。。更多stl样式 评论 2015年11月10日8:52
  • 1
    我发现有趣的是,与get<>方法不同,find方法不支持find(“SubNode.Attribute”)。您必须手动获取ptree中的SubNode子节点,并在子实例上运行find,
    – 窒息
    评论 2015年11月10日10:21
  • 2
    node.count也不适用于嵌套键,例如“child.subchild”。到目前为止,我发现唯一有效的是node.get_child_optional,如下面的答案所示stackoverflow.com/a/25389349/844728 评论 2019年11月14日10:26
  • 从之前的评论来看查找()是检查直接子项是否存在的最快方法,因为函数不必分割路径(与获取儿童选项(),确实如此)。
    – ζ42
    评论 2022年6月8日10:34
6

包括以下内容:

#包括<boost/optional/optional.hpp>

删除常数:

boost::可选<ptree&>child=node.get_child_optional(“possibly_missing_node”);if(!child){//缺少子节点}
2
  • 6
    虽然你的答案是有效的,但你抄袭了另一个几乎3年前被接受的答案(没有透露!)。你能解释一下你为什么要做这些改变吗?这可能更适合作为评论。
    – 埃弗里
    评论 2014年8月19日17:28
  • 2
    我投票否决了你,因为你没有添加到解决方案中-也许如果你改变的不仅仅是删除常量,那么我会投赞成票
    – 塞鲁普
    评论 2016年9月14日9:19
0

另一种可以使用的方法是,在您不想检查某些潜在的缺失子节点时使用。尝试使用迭代器:

if(node.begin()!=node.end()){//节点没有子节点[ren]//用于处理子节点的代码}
  • 这不是我们要问的问题 评论 2022年5月19日15:25
  • @MadPhysicist虽然这不是确切的问题,但它非常优雅,以防您只需要确定节点是否有子节点。在区分json数组元素和非数组元素时,我正是需要这样做的。我投了赞成票。
    – 开发版
    评论 2023年2月13日22:00
  • @我是这里投票系统的忠实粉丝:我不喜欢这个答案,所以我投了反对票;你喜欢它并且投了赞成票。我们俩都必须提出合理的理由,每个人都可以继续他们的项目。 评论 2023年2月13日22:02
0

您可以使用count()检查标记是否存在

typedef boost::属性树pt;pt::ptree树;pt::read_xml(文件名,树);int bodyCount=tree.count(“body”);if(bodyCount==0){cout<<“Failed:body tag not found”<<endl;返回-1;}

你的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览已标记的其他问题问你自己的问题.