如何从 GPX 文件中提取数据(并解析 gpx 文件)?
How to extract data from GPX file (and to parse gpx file)?
我正在 Linux 下的 bash 中编码。我正在尝试提取一系列 gpx 文件中每个轨道的 轨道名称 和 第一个时间戳。
我尝试使用以下命令(和其他变体)使用 xmllint 解析 gpx 文件:
xmllint --xpath "//gpx/trk/name/text()" test.gpx
xmllint --xpath "//gpx/trk/trkseg[1]/time/text()" test.gpx
失败并显示 return 消息:XPath set is empty
这里是文件的例子test.gpx
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<gpx creator="www.flyisfun.com" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<trk>
<name>Track_n1</name>
<trkseg>
<trkpt lat="-48.843895" lon="10.9835696">
<ele>126.75549</ele>
<time>2016-04-16T11:05:00Z</time>
</trkpt>
<trkpt lat="-48.843254" lon="11.9823042">
<ele>126.90486</ele>
<time>2016-04-16T11:05:05Z</time>
</trkpt>
</trkseg>
</trk>
</gpx>
我期待得到这个测试用例
Track_n1
2016-04-16T11:05:00Z
我想知道为什么带有 xmllint 的命令不起作用,以及我是否可以在不改变原始 gpx 文件的情况下调整它们来工作。
感谢您的帮助。
XML 示例包含默认命名空间 xmlns="http://www.topografix.com/GPX/1/1"
。 xmllint --shell
结合 setns
可用于获取值。
将默认(空)命名空间更改为已知命名空间:
echo -e 'setns ns=http://www.topografix.com/GPX/1/1\ncat //ns:gpx/ns:trk/ns:name/text()' \
| xmllint --shell test.xml | grep -Ev '^([/]| [-])'
结果:
Track_n1
local-name()
xml 函数也可以使用,但有时会给出复杂的 xpath 表达式,难以阅读。
如果您对 xmllint 的替代方案持开放态度,xmlstarlet is a good one. There are quite a few commands in xmlstarlet, but for just querying data sel
(select) 就可以了。
我喜欢将命名空间绑定到前缀或使用 _
作为默认命名空间前缀的方式(在版本 1.5.0+ 中)。 See here for more details. 相比 xmllint 的管道回显,我更喜欢它。
将默认名称空间绑定到前缀的示例...
xmlstarlet sel -N g="http://www.topografix.com/GPX/1/1" -t -m "/g:gpx/g:trk" -v "g:name" -n -v "g:trkseg/g:trkpt[1]/g:time" -n test.gpx
使用_
作为默认命名空间前缀的示例...
xmlstarlet sel -t -m "/_:gpx/_:trk" -v "_:name" -n -v "_:trkseg/_:trkpt[1]/_:time" -n test.gpx
以上两个示例均产生以下输出...
Track_n1
2016-04-16T11:05:00Z
我已成功将我的 Garmin GPX 转换为此处给出的解决方案中的文本格式。以下是一些有效的语法:
xmlstarlet sel -N g="http://www.topografix.com/GPX/1/1" -T -t -m "/g:gpx/g:trk/g:trkseg/g:trkpt" -v "@lat" -o "|" -v "@lon" -o "|" -v "g:ele" -o "|" -v "g:time" -n my_track.gpx
xmlstarlet sel -N g="http://www.topografix.com/GPX/1/1" -T -t -m "/g:gpx/g:trk/g:trkseg/g:trkpt" -v "concat(@lat,'|',@lon,'|',g:ele,'|',g:time)" -n my_track.gpx
xmlstarlet sel -T -t -m "/_:gpx/_:trk/_:trkseg/_:trkpt" -v "concat(@lat,'|',@lon,'|',_:ele,'|',_:time)" -n my_track.gpx
xmlstarlet select --text --template --match "/_:gpx/_:trk/_:trkseg/_:trkpt" --value-of "concat(@lat,'|',@lon,'|',_:ele,'|',_:time)" --nl my_track.gpx
也可以用perl解决:
#!/usr/bin/perl
# https://unix.stackexchange.com/questions/343636/from-gpx-to-csv-file
use warnings;
use strict;
use XML::Twig;
my $xml = XML::Twig -> new -> parsefile('my_track.gpx');
foreach my $wpt ( $xml -> get_xpath('/gpx/trk/trkseg/trkpt') ) {
print $wpt -> att('lat') . "|" . $wpt -> att('lon') . "|" . $wpt -> first_child_text('ele') . "|" . $wpt -> first_child_text('time') . "\n";
}
我正在 Linux 下的 bash 中编码。我正在尝试提取一系列 gpx 文件中每个轨道的 轨道名称 和 第一个时间戳。
我尝试使用以下命令(和其他变体)使用 xmllint 解析 gpx 文件:
xmllint --xpath "//gpx/trk/name/text()" test.gpx
xmllint --xpath "//gpx/trk/trkseg[1]/time/text()" test.gpx
失败并显示 return 消息:XPath set is empty
这里是文件的例子test.gpx
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<gpx creator="www.flyisfun.com" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<trk>
<name>Track_n1</name>
<trkseg>
<trkpt lat="-48.843895" lon="10.9835696">
<ele>126.75549</ele>
<time>2016-04-16T11:05:00Z</time>
</trkpt>
<trkpt lat="-48.843254" lon="11.9823042">
<ele>126.90486</ele>
<time>2016-04-16T11:05:05Z</time>
</trkpt>
</trkseg>
</trk>
</gpx>
我期待得到这个测试用例
Track_n1
2016-04-16T11:05:00Z
我想知道为什么带有 xmllint 的命令不起作用,以及我是否可以在不改变原始 gpx 文件的情况下调整它们来工作。
感谢您的帮助。
XML 示例包含默认命名空间 xmlns="http://www.topografix.com/GPX/1/1"
。 xmllint --shell
结合 setns
可用于获取值。
将默认(空)命名空间更改为已知命名空间:
echo -e 'setns ns=http://www.topografix.com/GPX/1/1\ncat //ns:gpx/ns:trk/ns:name/text()' \
| xmllint --shell test.xml | grep -Ev '^([/]| [-])'
结果:
Track_n1
local-name()
xml 函数也可以使用,但有时会给出复杂的 xpath 表达式,难以阅读。
如果您对 xmllint 的替代方案持开放态度,xmlstarlet is a good one. There are quite a few commands in xmlstarlet, but for just querying data sel
(select) 就可以了。
我喜欢将命名空间绑定到前缀或使用 _
作为默认命名空间前缀的方式(在版本 1.5.0+ 中)。 See here for more details. 相比 xmllint 的管道回显,我更喜欢它。
将默认名称空间绑定到前缀的示例...
xmlstarlet sel -N g="http://www.topografix.com/GPX/1/1" -t -m "/g:gpx/g:trk" -v "g:name" -n -v "g:trkseg/g:trkpt[1]/g:time" -n test.gpx
使用_
作为默认命名空间前缀的示例...
xmlstarlet sel -t -m "/_:gpx/_:trk" -v "_:name" -n -v "_:trkseg/_:trkpt[1]/_:time" -n test.gpx
以上两个示例均产生以下输出...
Track_n1
2016-04-16T11:05:00Z
我已成功将我的 Garmin GPX 转换为此处给出的解决方案中的文本格式。以下是一些有效的语法:
xmlstarlet sel -N g="http://www.topografix.com/GPX/1/1" -T -t -m "/g:gpx/g:trk/g:trkseg/g:trkpt" -v "@lat" -o "|" -v "@lon" -o "|" -v "g:ele" -o "|" -v "g:time" -n my_track.gpx
xmlstarlet sel -N g="http://www.topografix.com/GPX/1/1" -T -t -m "/g:gpx/g:trk/g:trkseg/g:trkpt" -v "concat(@lat,'|',@lon,'|',g:ele,'|',g:time)" -n my_track.gpx
xmlstarlet sel -T -t -m "/_:gpx/_:trk/_:trkseg/_:trkpt" -v "concat(@lat,'|',@lon,'|',_:ele,'|',_:time)" -n my_track.gpx
xmlstarlet select --text --template --match "/_:gpx/_:trk/_:trkseg/_:trkpt" --value-of "concat(@lat,'|',@lon,'|',_:ele,'|',_:time)" --nl my_track.gpx
也可以用perl解决:
#!/usr/bin/perl
# https://unix.stackexchange.com/questions/343636/from-gpx-to-csv-file
use warnings;
use strict;
use XML::Twig;
my $xml = XML::Twig -> new -> parsefile('my_track.gpx');
foreach my $wpt ( $xml -> get_xpath('/gpx/trk/trkseg/trkpt') ) {
print $wpt -> att('lat') . "|" . $wpt -> att('lon') . "|" . $wpt -> first_child_text('ele') . "|" . $wpt -> first_child_text('time') . "\n";
}