XML :: LibXML :: XPathContext解析Google Maps kml文件失败-找不到“何时”节点

时间:2019-01-08 19:42:06

标签: xml perl google-maps xpath kml

我无法让Perl使用XML :: LibXML读取Google LocationHistory.kml文件。 findnodes()找不到when标签,但确实找到了gx:coord标签。

如果我修改XML文件以将gx:放在when前面,则它可以工作。但这不是Google通过外卖服务产生的结果。

我想先读取他们的文件,而无需先对其进行修改。

输入数据文件-来自Google的Takeout服务

#++++++++++++++++++++++++++++++++++++++++
<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://www.opengis.net/kml/2.2' xmlns:gx='http://www.google.com/kml/ext/2.2'>
<Document>
    <Placemark>
        <open>1</open>
        <gx:Track>
            <altitudeMode>clampToGround</altitudeMode>
            <when>2018-05-17T15:59:24Z</when>
            <gx:coord>-98.0896248 29.997944600000004 258</gx:coord>
            <when>2018-05-17T15:59:24Z</when>
            <gx:coord>-98.0896248 29.997944600000004 258</gx:coord>
            <when>2018-05-17T15:59:23Z</when>
            <gx:coord>-98.0896647 29.9979384 258</gx:coord>
            <when>2018-05-17T15:45:14Z</when>
            <gx:coord>-98.0896772 29.9979363 258</gx:coord>
            <when>2018-05-17T15:40:08Z</when>
            <gx:coord>-98.0892224 29.9977119 262</gx:coord>
        </gx:Track>
    </Placemark>
</Document>
</kml>

我的密码

#++++++++++++++++++++++++++++++++++++++++
sub Test {
my ($infile) = @_;
my ($dom, $xpc, @gnodes, @wnodes);


$dom = XML::LibXML->load_xml(location => $infile);

$xpc = XML::LibXML::XPathContext->new($dom);
$xpc->registerNs('xmlns',    'http://www.opengis.net/kml/2.2');
$xpc->registerNs('xmlns:gx', 'http://www.google.com/kml/ext/2.2');

# should find 5
(@wnodes) = $xpc->findnodes('//when');
print 'XPath: //when      Matched:  ', scalar(@wnodes), "\n";;

# should find 5
(@gnodes) = $xpc->findnodes('//gx:coord');
say 'XPath: //gx:coord  Matched:  ', scalar(@gnodes);

};


THE OUTPUT - five <gx:coord> found, but zero <when> nodes found
searching for <gx:when> also produces zero results
#++++++++++++++++++++++++++++++++++++++++

Apple-iMac21:NewProgramLocal user$

XPath: //when      Matched:  0
XPath: //gx:coord  Matched:  5


Apple-iMac21:NewProgramLocal user$ 

2 个答案:

答案 0 :(得分:3)

XPath使用的前缀不必与XML中使用的前缀匹配。实际上,当在XML中使用默认名称空间时(如此处所示),即使XML中未使用XPath,也需要XPath前缀。只需选择对您有意义的前缀即可在XPath中使用。

还请注意,registerNs仅带前缀,因此请勿包括xmlns:

正在更改:

$xpc->registerNs('xmlns',    'http://www.opengis.net/kml/2.2');
$xpc->registerNs('xmlns:gx', 'http://www.google.com/kml/ext/2.2');
(@wnodes) = $xpc->findnodes('//when');

收件人:

$xpc->registerNs('main', 'http://www.opengis.net/kml/2.2');
$xpc->registerNs('gx',   'http://www.google.com/kml/ext/2.2');
(@wnodes) = $xpc->findnodes('//main:when');

产生预期的结果:

XPath: //when      Matched:  5
XPath: //gx:coord  Matched:  5

答案 1 :(得分:1)

bytepusher's answer above works, as does the second answer. adding "xmlns:" in front of the "when" tag produces the correct result and stays consistent with the file that is downloaded from Google using their Takeout feature (for "location history").

I was assuming xmlns acted as a default that didn't need to be specified in an xpath search, but that was a bad assumption.

Thanks for the help!