Skip to content

Instantly share code, notes, and snippets.

@ekuester
Last active May 19, 2018 08:27
Show Gist options
  • Save ekuester/dab505538bcf9d2cb476e58b9c5cbbc3 to your computer and use it in GitHub Desktop.
Save ekuester/dab505538bcf9d2cb476e58b9c5cbbc3 to your computer and use it in GitHub Desktop.
C++ program to read XML files using libxml++-3.0 especially for parsing GPX tracks
<?xml version="1.0" encoding="utf-8"?>
<gpx>
<trk>
<name>2017-02-22 16:56:53</name>
<extensions>
<color red="0.000000" green="0.000000" blue="1.000000" alpha="1.000000"/>
<area showArea="no" areaDistance="0.000000"/>
<directionArrows showDirectionArrows="yes"/>
<sync syncPhotosOniPhone="no"/>
<timezone offset="60"/>
</extensions>
<trkseg>
<trkpt lat="51.28240146678991" lon="6.472615096724101"><ele>22.36187744140625</ele>
<time>2017-02-22T15:56:53Z</time>
<extensions>
<speed>0</speed>
<length>0</length>
</extensions>
</trkpt>
<trkpt lat="51.28234530803866" lon="6.472765970981189">
<ele>31.2567138671875</ele>
<time>2017-02-22T15:56:55Z</time>
<extensions>
<speed>21.97897109127528</speed>
<length>0.01221053949515293</length>
</extensions>
</trkpt>
<trkpt lat="51.28234182954885" lon="6.472779801121422">
<ele>31.867431640625</ele>
<time>2017-02-22T15:57:20Z</time>
<extensions>
<speed>0.1491295442440743</speed>
<length>0.001035621835028294</length>
</extensions>
</trkpt>
<trkpt lat="51.28234371547706" lon="6.472773598513075">
<ele>31.71282958984375</ele>
<time>2017-02-22T15:57:21Z</time>
<extensions>
<speed>1.742676972686629</speed>
<length>0.000484076936857397</length>
</extensions>
</trkpt>
<trkpt lat="51.2823461881385" lon="6.472768737009235">
<ele>31.92791748046875</ele>
<time>2017-02-22T15:57:22Z</time>
<extensions>
<speed>1.603029663875792</speed>
<length>0.0004552936946604452</length>
</extensions>
</trkpt>
<trkpt lat="51.28234912180461" lon="6.472763875505396">
<ele>32.7633056640625</ele>
<time>2017-02-22T15:57:23Z</time>
<extensions>
<speed>1.742676972686629</speed>
<length>0.000484076936857397</length>
</extensions>
</trkpt>
<trkpt lat="51.28235218119926" lon="6.472758846363493">
<ele>32.965087890625</ele>
<time>2017-02-22T15:57:24Z</time>
<extensions>
<speed>1.808461361231</speed>
<length>0.0005023503781197223</length>
</extensions>
</trkpt>
<trkpt lat="51.28235469577022" lon="6.472755661240288">
<ele>33.3531494140625</ele>
<time>2017-02-22T15:57:25Z</time>
<extensions>
<speed>1.36706829071045</speed>
<length>0.0003676828279895702</length>
</extensions>
</trkpt>
<trkpt lat="51.2823583418981" lon="6.472750213003226">
<ele>30.20745849609375</ele>
<time>2017-02-22T15:57:26Z</time>
<extensions>
<speed>2.02192126919716</speed>
<length>0.0005616447969992111</length>
</extensions>
</trkpt>
<trkpt lat="51.28236513123966" lon="6.472743926575848">
<ele>30.3184814453125</ele>
<time>2017-02-22T15:57:27Z</time>
<extensions>
<speed>3.150936720590098</speed>
<length>0.0008752602001639161</length>
</extensions>
</trkpt>
<trkpt lat="51.28237439324267" lon="6.472739316529103">
<ele>30.4061279296875</ele>
<time>2017-02-22T15:57:28Z</time>
<extensions>
<speed>3.896744173750851</speed>
<length>0.001078257711860346</length>
</extensions>
</trkpt>
<trkpt lat="51.2823823979602" lon="6.472736466682025">
<ele>30.9833984375</ele>
<time>2017-02-22T15:57:29Z</time>
<extensions>
<speed>3.278114601555208</speed>
<length>0.000910587389320891</length>
</extensions>
</trkpt>
<trkpt lat="51.28239371352948" lon="6.472729844978519">
<ele>31.5540771484375</ele>
<time>2017-02-22T15:57:31Z</time>
<extensions>
<speed>2.404544495813693</speed>
<length>0.001335858053229829</length>
</extensions>
</trkpt>
<trkpt lat="51.28239367161996" lon="6.472719786694713">
<ele>31.32403564453125</ele>
<time>2017-02-22T15:57:32Z</time>
<extensions>
<speed>2.511464816834534</speed>
<length>0.0007040590131474508</length>
</extensions>
</trkpt>
<trkpt lat="51.28238616981663" lon="6.472695814451643">
<ele>30.8681640625</ele>
<time>2017-02-22T15:57:33Z</time>
<extensions>
<speed>6.714657589119293</speed>
<length>0.001865182663644248</length>
</extensions>
</trkpt>
<trkpt lat="51.28237389032848" lon="6.472665723419257">
<ele>30.39178466796875</ele>
<time>2017-02-22T15:57:34Z</time>
<extensions>
<speed>8.990488002378129</speed>
<length>0.002499161576274435</length>
</extensions>
</trkpt>
<trkpt lat="51.28236098219759" lon="6.47263311781592">
<ele>29.95721435546875</ele>
<time>2017-02-22T15:57:35Z</time>
<extensions>
<speed>9.660589052502658</speed>
<length>0.002683496959028516</length>
</extensions>
</trkpt>
<trkpt lat="51.28234631386704" lon="6.47259841673679">
<ele>29.427734375</ele>
<time>2017-02-22T15:57:36Z</time>
<extensions>
<speed>10.48952131951511</speed>
<length>0.002913755922087531</length>
</extensions>
</trkpt>
<trkpt lat="51.28232925669409" lon="6.472565559676357">
<ele>28.6324462890625</ele>
<time>2017-02-22T15:57:37Z</time>
<extensions>
<speed>10.69354163013018</speed>
<length>0.002970428230591717</length>
</extensions>
</trkpt>
<trkpt lat="51.28230955922164" lon="6.472532534977861">
<ele>28.34820556640625</ele>
<time>2017-02-22T15:57:38Z</time>
<extensions>
<speed>11.4274971161094</speed>
<length>0.003174304754474834</length>
</extensions>
</trkpt>
<trkpt lat="51.28228826918758" lon="6.472501019021936">
<ele>28.98126220703125</ele>
<time>2017-02-22T15:57:39Z</time>
<extensions>
<speed>11.61002414680897</speed>
<length>0.003225006707446936</length>
</extensions>
</trkpt>
<trkpt lat="51.28226526086338" lon="6.47247335874147">
<ele>30.054443359375</ele>
<time>2017-02-22T15:57:40Z</time>
<extensions>
<speed>11.51912216768657</speed>
<length>0.003199756157690713</length>
</extensions>
</trkpt>
<trkpt lat="51.28223894168742" lon="6.472443016251989">
<ele>30.06903076171875</ele>
<time>2017-02-22T15:57:41Z</time>
<extensions>
<speed>12.98265104775767</speed>
<length>0.003607541322708178</length>
</extensions>
</trkpt>
<trkpt lat="51.28220880874552" lon="6.472405381506749">
<ele>30.2454833984375</ele>
<time>2017-02-22T15:57:42Z</time>
<extensions>
<speed>15.30338157379246</speed>
<length>0.004251999278526248</length>
</extensions>
</trkpt>
</trkseg>
</trk>
</gpx>
/*
* File: main.cpp
* Processed by: kuestere
*
* retrieve and process information from a XML file
* get elements and from them the attributes and/or text content of child nodes
*
* compile and build with
* g++ 'pkg-config libxml++-3.0 --cflags --libs' -c main.cpp
* g++ main.o -o XMLParser 'pkg-config libxml++-3.0 --cflags --libs'
* chmod +x ./XMLParser
* ./XMLParser
*
* written to read GPX track files
*
* Created on 13. Mai 2018, 19:40
*/
#include <iostream>
#include <cstdlib>
#include <libxml++/libxml++.h>
using namespace std;
using namespace xmlpp;
int main(int argc, char* argv[])
{
// Parse the file
DomParser parser;
parser.parse_file("gpxtrack.xml");
Document* document = parser.get_document();
Element* root_node = document->get_root_node();
// Xpath query
// find all elements
// Element::NodeSet nodes(root_node->find("descendant::*"));
// find special elements
Element::NodeSet nodes(root_node->find("/gpx/trk/trkseg/trkpt"));
for (Element::NodeSet::iterator i = nodes.begin(); i != nodes.end(); ++i) {
Element* element = dynamic_cast<Element*> (*i);
cout << "Xpath name: " << element->get_name() << endl;
Element::AttributeList attributes = element->get_attributes();
for (Element::AttributeList::iterator a = attributes.begin(); a != attributes.end(); ++a) {
Attribute* attribute = dynamic_cast<Attribute*> (*a);
cout << "attribute: " << attribute->get_name() << " = " << attribute->get_value() << endl;
}
// three methods for obtaining text content from childs by iteration follow,
// decide youself which to use
// Method one
Node* child = element->get_first_child();
while (child) {
// test for TextNode
const auto text = dynamic_cast<const TextNode*>(child);
// better ignoring the indenting
bool content_exists = !(text && text->is_white_space());
if(content_exists) {
Element* el = dynamic_cast<Element*> (child);
if (el->has_child_text()) {
cout << el->get_name() << " = " << el->get_first_child_text()->get_content() << endl;
}
}
child = child->get_next_sibling();
}
// Method two
/*
Element::NodeList children = element->get_children();
for (Element::NodeList::iterator ch = children.begin(); ch != children.end(); ch++) {
// test for TextNode
const auto text = dynamic_cast<const TextNode*>(*ch);
// better ignoring the indenting
bool content_exists = !(text && text->is_white_space());
if(content_exists) {
Element* el = dynamic_cast<Element*> (*ch);
if (el->has_child_text()) {
cout << el->get_name() << " = " << el->get_first_child_text()->get_content() << endl;
}
}
}
*/
// Method three
/*
for (const auto& child : element->get_children()) {
// test for TextNode
const auto text = dynamic_cast<const TextNode*>(child);
// better ignoring the indenting
bool content_exists = !(text && text->is_white_space());
if(content_exists) {
Element* e = dynamic_cast<Element*> (child);
if (e->has_child_text()) {
cout << child->get_name() << " = " << e->get_first_child_text()->get_content() << endl;
}
}
}
*/
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment