XML :: LibXML :: XPathContext не в состоянии анализировать файл Google Maps kml - не находит «когда» узлы - PullRequest
0 голосов
/ 08 января 2019

Мне не удается заставить Perl читать файлы Google LocationHistory.kml с использованием XML :: LibXML. 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 голосов
/ 10 января 2019

ответ bytepusher выше работает, как и второй ответ. добавление «xmlns:» перед тегом «когда» дает правильный результат и соответствует файлу, загруженному из Google с помощью функции «Вынос» (для «истории местоположений»).

Я предполагал, что xmlns действовал по умолчанию, и его не нужно было указывать в поиске xpath, но это было неверное предположение.

Спасибо за помощь!

0 голосов
/ 09 января 2019

Префиксы, используемые 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
...