[erledigt] Pugixml Prog zeigt nicht alle Ergebnisse, loop



  • Hallo Community,

    ich möchte mit Pugixml ein Gpx-File auslesen, das zwei Tracks enthält.

    Die Ausgabe zeigt nur die Daten von Track01.
    Wie kann ich auch Track02 auslesen?

    Vielen Dank!

    #include "pugixml.hpp"
    #include <string.h>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    int main()
    
    {
    
    string trck_name;
    
    
        pugi::xml_document doc;
        if (!doc.load_file("sample.gpx")) return -1;
    
    
        pugi::xml_node trkseg = doc.child("gpx").child("trk").child("trkseg");
    
        trck_name = doc.child("gpx").child("trk").child("name").child_value();
        cout << "trk_name: " << trck_name << endl;
    
    
        for (pugi::xml_node trkpt = trkseg.child("trkpt"); trkpt; trkpt = trkpt.next_sibling("trkpt")){
            std::cout << "Trkpt " << trkpt.attribute("lat").value() << endl;
       	}
    
             cout << endl;
    
     }
    
    

    XML-Datei:

    <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
    <gpx>
     <trk>
      <name>Track01</name>
      <trkseg>
       <trkpt lat="50.96670798" lon="6.95335678"/>
       <trkpt lat="50.96784147" lon="6.95306513"/>
       <trkpt lat="50.96882844" lon="6.95283205"/>
       <trkpt lat="50.96892064" lon="6.95280729"/>
       <trkpt lat="50.96893430" lon="6.95385145"/>
      </trkseg>
     </trk>
     <trk>
       <name>Track02</name>
      <trkseg>
       <trkpt lat="50.96652695" lon="6.95481205"/>
       <trkpt lat="50.96652325" lon="6.95494941"/>
       <trkpt lat="50.96650959" lon="6.95523542"/>
       <trkpt lat="50.96647885" lon="6.95577927"/>
       <trkpt lat="50.96644470" lon="6.95629495"/>
      </trkseg>
     </trk>
    </gpx>
    

    Ergebnis:

    trk_name: Track01
    Trkpt 50.96670798
    Trkpt 50.96784147
    Trkpt 50.96882844
    Trkpt 50.96892064
    Trkpt 50.96893430
    
    
    Process returned 0 (0x0)   execution time : 0.004 s
    Press ENTER to continue.
    
    

    Gruß

    Piet



  • doc.child("gpx").child("trk").child("trkseg");

    Ich vermute das liefert dir nur das jeweils erste tag im document.
    keine Ahnung was Pugixml aus gleichlautenden Tags auf selber ebene macht ...
    Theorethisch solltest unabhängig vom namen über parent / child / nextSibling durch die knoten iterieren können, was für DOM Parser meist aber eher am Zweck vorbei geht ....

    Ich vermute die xml dateien könnten auch richtig groß werden .... dann würd ich statt einem DOM Parser eher einen SAX/Event parser in Erwägung ziehen (kann man besser optimieren)

    https://de.wikipedia.org/wiki/Simple_API_for_XML

    Je nachdem was du schon hernimmst, gibts da auch etliche ... expat, der xerces, Qt hat auch einen ....



  • @Piet

    Naja, du iterierst doch auch schon über trkptdes Tracks genau so kannst du auch über trk iterieren.



  • Hallo,

    mein Problem ist, das ich die "Mechanik" von pugixml nicht verstehe...

    Hier ein Test mit zwei for Schleifen:

    #include "pugixml.hpp"
    #include <string.h>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    int main()
    
    {
    
    string trck_name;
    
    
        pugi::xml_document doc;
        if (!doc.load_file("sample.gpx")) return -1;
    
    
        pugi::xml_node trk = doc.child("gpx").child("trk");
        //pugi::xml_node trkseg = doc.child("gpx").child("trk").child("trkseg");
        //pugi::xml_node trkpt = doc.child("gpx").child("trk").child("trkseg").child("trkpt");
    
    
        for (pugi::xml_node trk = doc.child("gpx").child("trk"); trk;trk = trk.next_sibling("trk")) {
    
        trck_name = trk.child("name").child_value();
        cout << "trk_name: " << trck_name << endl;
    
            for (pugi::xml_node trkpt = doc.child("gpx").child("trk").child("trkseg").child("trkpt"); trkpt; trkpt = trkpt.next_sibling("trkpt")){
    
    
                std::cout << "Trkpt " << doc.child("gpx").child("trk").child("trkseg").child("trkpt").attribute("lat").value() << endl;
            }
    
         }
    
         cout << endl;
    
     }
    
    

    Die Namen der zwei Tracks werden angezeigt, aber wieder nur die Attribute des ersten Tracks.

    Grup

    Piet



  • Du musst in der zweiten Schleife auch den Knoten aus der ersten Schleife verwenden.

    So was in der Richtung (ungetestet):

    int main()
    {
        string trck_name;
        pugi::xml_document doc;
        if (!doc.load_file("sample.gpx")) return -1;
    
        for (pugi::xml_node trk = doc.child("gpx").child("trk"); trk;trk = trk.next_sibling("trk")) {
    
            trck_name = trk.child("name").child_value();
            cout << "trk_name: " << trck_name << endl;
    
            for (pugi::xml_node trkpt = trk.child("trkseg").child("trkpt"); trkpt; trkpt = trkpt.next_sibling("trkpt")){
    
                std::cout << "Trkpt " << trkpt.attribute("lat").value() << endl;
            }
    
         }
    
         cout << endl;
    
     }
    


  • Hallo Schlangenmensch,

    danke!

    Funktioniert!

    Gruß

    Piet


Anmelden zum Antworten