2011-09-27 41 views
30

Sto provando a scrivere un parser XML, analizzando il file XML su un boost::property_tree e ho trovato questo problema. Come posso verificare (rapidamente) se esiste un figlio di una certa proprietà?Boost PropertyTree: verifica se esiste un figlio

Ovviamente potrei scorrere tutti i bambini utilizzando BOOST_FOREACH - tuttavia, non c'è una soluzione migliore a questo?

risposta

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

al fine di ottenere il tuo esempio al lavoro ho dovuto togliere il 'const' - Potrebbe spiegare il motivo per cui si utilizza 'const ' Qui ? – serup

+0

Per la sicurezza. Durante la lettura della configurazione ci può essere un piccolo motivo per modificare i valori. Una rapida ricerca mi mostra che ptree ha ancora (in boost 1.61.0) un overload get_child_optional che ritorna facoltativo , quindi il tuo errore sarà correlato a ciò che fai successivamente con il valore. – RobH

17

Ecco un paio di altre alternative:

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

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

Mi piace il 2 ° ... altro stile – anhoppe

+1

Trovo interessante notare che diversamente dal metodo get <> il metodo find non fornisce supporto per find ("SubNode.Attribute"). Devi ottenere manualmente il figlio SubNode nel ptree ed eseguire find sull'istanza figlio, – anhoppe

+0

stranamente node.count non funziona per me anche quando è lì ... –

1

Mentre queste soluzioni potrebbero apparire per evitare l'iterazione sopra l'albero, basta tenere a mente che sotto le coperte che stanno ancora facendo esattamente questo, in modo da stai rendendo il tuo algoritmo potenzialmente n^2 ... se sei preoccupato per le prestazioni e hai memoria da risparmiare, potresti usare un contenitore di mappe per ricerche rapide.

+0

2n invece di n^2 in realtà: D. Qual è ancora n alla fine ... – Ioanna

+0

sembra interessante - forse potresti scrivere un piccolo esempio di questo? – serup

5

Includi questo:

#include <boost/optional/optional.hpp> 

Rimuovere il const:

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

Mentre la tua risposta è valida, hai copiato la maggior parte di un'altra risposta (senza divulgazione!) Che è stata accettata e ha quasi 3 anni. Puoi almeno spiegare perché hai apportato le modifiche che hai fatto? Questo è probabilmente meglio servito come commento. – Avery

+0

Ti ho votato perché non stai aggiungendo alla soluzione - forse se avessi cambiato più di una semplice rimozione di const, avrei votato – serup