2011-09-27 189 views
30

我正在嘗試編寫XML解析器,將XML文件解析爲boost::property_tree,並且遇到了此問題。我如何檢查(快速)某個財產的孩子是否存在?Boost PropertyTree:檢查孩子是否存在

很明顯,我可以迭代所有使用BOOST_FOREACH的孩子 - 但是,沒有更好的解決方案嗎?

回答

37
optional< const ptree& > child = node.get_child_optional("possibly_missing_node"); 
if(!child) 
{ 
    // child node is missing 
} 
+0

爲了得到你的榜樣工作,我不得不刪除了「常量」 - 你能解釋一下你爲什麼用「常量' 這裏 ? – serup

+0

爲了安全起見。在閱讀配置時,可能沒有理由修改值。快速搜索表明,ptree仍然具有(在boost 1.61.0中)一個get_child_optional重載,該重載返回可選的,所以你的錯誤將與隨後對值做什麼有關。 – RobH

17

這裏有一對夫婦的其他替代方案:

if(node.count("possibliy_missing") == 0) 
{ 
    ... 
} 

ptree::const_assoc_iterator it = ptree.find("possibly_missing"); 
if(it == ptree.not_found()) 
{ 
    ... 
} 
+1

我喜歡第二個...更多stl風格 – anhoppe

+1

我發現有趣的是,與get <>方法不同,find方法不提供對find(「SubNode.Attribute」)的支持。您必須手動獲取ptree中的子節點子節點,然後在子節點上運行查找, – anhoppe

+0

奇怪地是,node.count即使在那裏時也不適用於我... –

1

雖然這些解決方案可能會出現以避免遍歷樹,只是要記住,在幕後他們仍然做的正是這一點,所以你正在使你的算法潛在n^2 ...如果你關心性能和內存空閒,你可以使用地圖容器進行快速查找。

+0

2n而不是n^2實際上:D。哪一個最後還是n ... – Ioanna

+0

聽起來有趣 - 也許你可以寫一個小例子呢? – serup

5

包含此:

#include <boost/optional/optional.hpp> 

刪除const

boost::optional< ptree& > child = node.get_child_optional("possibly_missing_node"); 
if(!child) 
{ 
    // child node is missing 
} 
+5

雖然你的答案是有效的,但你複製了大部分被接受並且近3年的答案(沒有公開!)。你至少能解釋你​​爲什麼做了改變嗎?這可能更好地作爲評論。 – Avery

+0

我投你一票,因爲你沒有加入解決方案 - 也許如果你改變的不僅僅是刪除常量,那麼我會投票贊成 – serup