2011-01-04 14 views
14

Przykro mi, wcześniej zadałem pytanie dotyczące tego samego tematu, ale mój problem dotyczy innego aspektu opisanego tam (How to iterate a boost...).Zwiększanie iteratorów Property_Tree, jak sobie z nimi radzić?

Spójrz na poniższy kod:

#include <iostream> 
#include <string> 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 
#include <boost/algorithm/string/trim.hpp> 
int main(int argc, char** argv) { 
    using boost::property_tree::ptree; 
    ptree pt; 
    read_xml("try.xml", pt); 
    ptree::const_iterator end = pt.end(); 
    for (ptree::const_iterator it = pt.begin(); it != end; it++) 
      std::cout << "Here " << it->? << std::endl; 
} 

Jak już powiedziano nam powiedziano w pytaniu wspomniałem, istnieje możliwość korzystania z iteratorów na property_tree w Boost, ale nie wiem co wpisz i jakie metody lub właściwości mogę użyć.

Zakładam, że musi to być kolejny numer ptree lub coś reprezentującego kolejną hierarchię xml do ponownego przeglądania (jeśli chcę), ale dokumentacja na ten temat jest bardzo zła. Nie wiem dlaczego, ale w dokumentach doładowania nie mogę znaleźć niczego dobrego, po prostu coś o makrze do przeglądania węzłów, ale takie podejście jest tym, czego chciałbym uniknąć.

Tak więc na moje pytanie tutaj: Jak uzyskać Iterator na ptree, jak mogę uzyskać dostęp do nazwy węzła, wartości, parametry (węzeł w pliku xml)? Thankyou

Odpowiedz

18

zgadzam się z Andry i znaleźć dokumentację property_tree być bardzo minimalne przynajmniej. Potrzebowałem ptree do ładowania identycznych obiektów z różnymi ustawieniami i miałem kłopot z ustaleniem, co iterator wykonuje iteracyjnie, jaki typ wraca i czy pozostanie na poziomie obiektów, czy przejdzie przez każdy węzeł podobny do BFS. Wreszcie udało mi się dostać mój kod działa dla przypadku podobnym do następującego: Plik

ustawienia:

<object1> 
    <enable>true</enable> 
    <label>hello</label> 
</object1> 
<object2> 
    <enable>false</enable> 
    <label>goodbye</label> 
</object2> 

pierwsze, dodałem konstruktora dla mojego obiektu, która może zainicjować na ptree.Należy pamiętać, że używam get z domyślnej opcji, aby zapobiec wyjątek na nieudanej get() 's:

object::object(const boost::property_tree::ptree &pt_) 
{ 
    enable = pt_.get<bool>("enable", true); // usage is: get<type>(path, default) 
    label = pt_.get<std::string>("label", "empty"); 
} 

Wreszcie następujące ładunki kod obu obiektów i umieszcza je na mapie:

std::map<std::string, my_object> objects_map; 

// parse settings file and add loggers 
if(filesystem::exists(logger_settings_file)) 
{ 
    boost::property_tree::ptree pt; 

    read_xml(logger_settings_file, pt); 
    BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt) 
    { 
     objects_map[v.first] = my_object(v.second); 
    } 
} 

Tak więc, aby odpowiedzieć na moje własne pytania:

  • The iteracje iteracyjnej ponad pliku ustawień bez schodząc do niższych poziomów. Uruchamiając powyższy kod, zauważysz, że pętla iteruje dwa razy - raz dla każdego obiektu w pliku XML.
  • Iterator zwraca obiekt value_type, który przypomina parę i ma akcesory first i second. v.first to std :: string przechowujący węzeł nadrzędny (w moim przypadku "object1", "object2"), a v.second to boost::property_tree::ptree, który może być użyty do parsowania pól obiektu.
+0

Dziękuję bavaza ... Twoja odpowiedź wyjaśniła lepsze podejście ... Podobało mi się. Dziękuję – Andry

+0

@Andry. Zdrowie przyjacielu. – bavaza

0

Powinieneś mieć wcześniejszą wiedzę na temat pliku właściwości wejściowych.

Drzewo właściwości wzmocnienia nie jest ogólnym analizatorem dokumentów. Wykona parsowanie i da dostęp do danych, ale musi je zlokalizować ręcznie.

Nie wiem, czy istnieje metoda nawigacji w całym dokumencie, ale jeśli potrzebujesz tylko właściwości własnego pliku, możesz to zrobić za pomocą bardzo prostego kodu.

Z boost documentation:

1) Wersja rzutu (get):

ptree pt; 
/* ... */ 
float v = pt.get<float>("a.path.to.float.value"); 

2) Wersja domyślna wartość (get):

ptree pt; 
/* ... */ 
float v = pt.get("a.path.to.float.value", -1.f); 

3) opcjonalnie wersja (get_optional):

ptree pt; 
/* ... */ 
boost::optional<float> v = pt.get_optional<float>("a.path.to.float.value"); 
19

druku pełne drzewo:

void print(boost::property_tree::ptree const& pt) 
{ 
    using boost::property_tree::ptree; 
    ptree::const_iterator end = pt.end(); 
    for (ptree::const_iterator it = pt.begin(); it != end; ++it) { 
     std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl; 
     print(it->second); 
    } 
} 
+0

Witam, Właśnie odrzuciłem anonimową edycję tego wpisu (ponieważ zmieniła ona Twój kod). Możesz chcieć [sprawdzić to] (http://stackoverflow.com/suggested-edits/264840), aby sprawdzić, czy powinien on zostać włączony do twojej odpowiedzi. – Benjol

+0

@Benjol: tnx. Było dobrze, więc go włączyłem. –

Powiązane problemy