Ваш код начинается с использования XML::LibXML::Reader
API, а затем позже использует XML::LibXML->load_xml
для создания DOM из части документа.API XML::LibXML::Reader
обычно используется только с большими XML-документами, которые занимают большие объемы памяти при загрузке в качестве DOM.Если ваш XML-документ не очень большой, то гораздо проще использовать такой подход, как ответ ikegami , который просто использует DOM API для загрузки всего документа, а затем запрашивает его с помощью XPath.
Однако, если у вас действительно есть огромный XML-документ, то вам может быть интересно решить проблему с помощью Reader API:
my $sitemap_uri = 'http://www.sitemaps.org/schemas/sitemap/0.9';
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs(sm => $sitemap_uri);
my $reader = XML::LibXML::Reader->new(location => './sitemap.xml');
while ($reader->read) {
$reader->nextElement('url', $sitemap_uri) or last;
my $doc = $reader->copyCurrentNode(1);
say "Doc = $doc";
my ($loc) = $xpc->findnodes('//sm:loc', $doc);
say "Loc = $loc";
}
Вызов $reader->nextElement
- это быстрый способ перейти к следующему вхождению.определенного элемента.В этом примере я сопоставил и имя элемента, и его пространство имен.
Вызов $reader->copyCurrentNode(1)
- это удобный метод, который возвращает этот узел и все его дочерние узлы в виде фрагмента DOM.Вам нужно будет использовать XML::LibXML::XPathContext
для запроса этого DOM с помощью операторов XPath с учетом пространства имен.
В моем учебнике по XML :: LibXML содержится охват работы с пространствами имен XML , а также работа с большими документами .