xml - XML::LibXML::XPathContext 无法解析 Google Maps kml 文件 - 找不到“何时”节点
问题描述
我无法让 PerlLocationHistory.kml
使用 XML::LibXML 读取 Google 文件。findnodes()
没有找到when
标签,但确实找到gx:coord
了标签。
如果我将 XML 文件修改为放在gx:
前面when
,它可以工作。但这不是谷歌通过他们的外卖服务生产的。
我想阅读他们的文件而不先修改它。
输入数据文件 - 来自 Google 的外卖服务
#++++++++++++++++++++++++++++++++++++++++
<?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$
解决方案
XPath 使用的前缀不必与 XML 中使用的前缀匹配。事实上,当在 XML 中使用默认名称空间时(就像这里的情况),XPath 需要前缀,即使在 XML 中没有使用任何前缀。只需选择对您有意义的前缀以在 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
推荐阅读
- php - 如何使用 php 将 .pkpass 文件保存在服务器目录中
- reactjs - 如果没有 React-hooks 和类组件而不是函数组件(按钮侧边栏),这个 React 代码会如何?
- ffmpeg - 如何使用 ffmpeg 将多个音频文件(过滤一个)添加到视频中?
- matlab - 我的 Matlab 程序没有输出正确的信号
- powershell - 连接目录中的所有 .csv 文件,包括文件名并控制数据格式
- ruby-on-rails - Rails - 为模型添加额外的列或创建额外的关联(表)?
- java - 在 Java 中使用 Scanner 函数的意外行为
- apache-kafka - KSQL Table-Table Left outer Join 多次发出相同的连接结果
- java - 迁移到 Androidx 后无法解析方法 setAdapter
- python - pandas groupby 根据条件计数