Przede wszystkim powiem, że wydaje mi się, jak należy to zrobić, ale mój kod nie skompiluje się tak, jak bym próbował. Swoje założenie oparłem na tym oficjalnym przykładzie pustej sztuczki ptree< /a>. Tam znajdziesz następną linię:

  const ptree &settings = pt.get_child("settings", empty_ptree<ptree>());

Co pokazuje, że jest (lub powinno być) możliwe wydobycie podtree z ptree.

Więc założyłem, że możemy iterować przez ptree z czymś takim jak BOOST_FOREACH w taki sposób:

BOOST_FOREACH(const boost::property_tree::ptree &v,
    config.get_child("servecies"))
{

}

Ale otrzymuję kolejny błąd:

Błąd 1 błąd C2440: „inicjowanie”: nie można przekonwertować z „std::pair<_Ty1,_Ty2>” na „const boost::property_tree::ptree &”

Lub jeśli spróbuję

BOOST_FOREACH(boost::property_tree::ptree &v,
    config.get_child("servecies", boost::property_tree::empty_ptree<boost::property_tree::ptree>()))
{

}

Dostaję:

Błąd 1 błąd C2039: „empty_ptree”: nie jest członkiem „boost::property_tree”

Więc co mam zrobić: jak przejść przez Boost Ptree i uzyskać sub-Ptree?

Aktualizacja: Próbowałem też takiego kodu

    BOOST_FOREACH(boost::property_tree::ptree::value_type &v,
    config.get_child("path.to.array_of_objects"))
{
    std::cout << "First data: " << v.first.data() << std::endl;
    boost::property_tree::ptree subtree = (boost::property_tree::ptree) v.second ;
    BOOST_FOREACH(boost::property_tree::ptree::value_type &vs,
        subtree)
    {
        std::cout << "Sub data: " << vs.first.data() << std::endl;
    }
}

To się kompiluje, nie wyrzuca żadnych wyjątków, ale nie wylicza żadnych Sub data, po prostu omija ten cykl.

Aktualizacja 2:

Hm... prawdopodobnie coś poszło nie tak w moim xml - teraz otrzymuję poprawne wyniki z tym kodem.

31
Rella 12 lipiec 2011, 00:49

3 odpowiedzi

Najlepsza odpowiedź

Iteratory drzewa właściwości wskazują pary w postaci (key, tree) typu ptree::value_type. Standardowa pętla do iteracji przez dzieci węzła w path wygląda zatem tak:

BOOST_FOREACH(const ptree::value_type &v, pt.get_child(path)) {
    // v.first is the name of the child.
    // v.second is the child tree.
}
32
antonakos 12 lipiec 2011, 03:39
Moim problemem jest to, że mam jakąś tablicę obiektów. Mam więc na przykład { "servecie": { "module": [ "plik", "Admin", "HR" ] } "servecie": { "module": [ "plik", "Admin", "HR" ] } } i muszę pobrać każdy obiekt jako oddzielne ptree. Czy coś takiego jest możliwe?
 – 
Rella
12 lipiec 2011, 04:07
1
Tak. Wartości v.second będą pdrzewami obiektów tablicy.
 – 
antonakos
12 lipiec 2011, 04:30

Używając C++11, możesz użyć następującego, aby przejść przez wszystkie dzieci węzła w path:

ptree children = pt.get_child(path);
for (const auto& kv : children) {
    // kv is of type ptree::value_type
    // kv.first is the name of the child
    // kv.second is the child tree
}
27
AlexG 30 październik 2019, 13:12
1
Moim zdaniem lepsze rozwiązanie, ale może trochę bardziej na przykład byłoby dobre.
 – 
gauteh
27 kwiecień 2014, 00:23

Miałem ten sam problem z iteracją przez podwęzły JSON

boost::property_tree::read_json(streamJSON, ptJSON);

Jeśli masz strukturę taką jak:

{
 playlists: [ {
   id: "1",
   x: "something"
   shows: [
    { val: "test" },
    { val: "test1" },
    { val: "test2" }
   ]
 },
 {
   id: "2"
   x: "else",
   shows: [
    { val: "test3" }
   ]
 }
 ]
}

Możesz iterować przez węzły podrzędne w ten sposób:

BOOST_FOREACH(boost::property_tree::ptree::value_type &playlist, ptJSON.get_child("playlists"))
{
    unsigned long uiPlaylistId = playlist.second.get<unsigned long>("id");
    BOOST_FOREACH(boost::property_tree::ptree::value_type &show, playlist.second.get_child("shows."))
    {
       std::string strVal = show.second.get<std::string>("val");
    }
}

Nie mogłem znaleźć nic na temat selektora ścieżek "pokazuje". aby wybrać podtablicę. (zwróć uwagę na kropkę na końcu)

Trochę dobrej dokumentacji można znaleźć tutaj: http://kaalus.atspace.com/ptree/doc/index.html

Mam nadzieję, że to komuś pomoże.

8
Evalds Urtans 31 grudzień 2012, 15:48