/ / Estrarre un nodo con LibXML - perl, xpath, xml-parsing, libxml2

Estrazione di un nodo con LibXML - perl, xpath, xml-parsing, libxml2

Questo può essere molto per me principiante, ma sono un novizio in Perl LibXML (e XPath per quella materia). Ho questo documento XML:

<Tims
xsi:schemaLocation="http://my.location.com/namespace http://my.location.com/xsd/Tims.xsd"
xmlns="http://my.location.com/namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">
<Error>Too many entities for operation.  Acceptable limit is 5,000 and 8,609 were passed in.</Error>
<Timestamp>2012-07-27T12:06:24-04:00</Timestamp>
<ExecutionTime>41.718</ExecutionTime>
</Tims>

Tutto quello che voglio fare è ottenere il valore di <Error>. È tutto. Ho provato molti approcci, di recente Questo uno. Ho letto i documenti fino in fondo. Questo è quello che ho attualmente nel mio codice:

#!/usr/bin/perl -w

my $xmlString = <<XML;
<?xml version="1.0" encoding="ISO-8859-1"?>
<Tims
xsi:schemaLocation="http://my.location.com/namespace http://my.location.com/xsd/Tims.xsd"
xmlns="http://my.location.com/namespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink">
<Error>Too many entities for operation.  Acceptable limit is 5,000 and 8,609 were passed in.</Error>
<Timestamp>2012-07-27T12:06:24-04:00</Timestamp>
<ExecutionTime>41.718</ExecutionTime>
</Tims>
XML

use XML::LibXML;

my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($xmlString);
my $root = $doc->documentElement();
my $xpc = XML::LibXML::XPathContext->new($root);

$xpc->registerNs("x", "http://my.location.com/namespace");

foreach my $node ($xpc->findnodes("x:Tims/x:Error")) {
print $node->toString();
}

Qualche consiglio, link, qualsiasi cosa è apprezzata. Grazie.

risposte:

2 per risposta № 1

Basta aggiungere un / all'inizio dell'XPath (ovvero in findnodes).


0 per risposta № 2

Il codice non funziona perché si utilizza l'elemento del documento <Tims> come nodo di contesto quando si crea il contesto XPath $xpc. Il <Error> element è un figlio immediato di questo, quindi tutto ciò che devi scrivere è

$xpc->findnodes("x:Error")

o un'alternativa è usare un XPath assoluto che specifica il percorso dalla radice del documento

$xpc->findnodes("/x:Tims/x:Error")

In questo modo non importa quale sia il nodo contestuale di $xpc è.

Ma il modo corretto è dimenticare di recuperare del tutto il nodo dell'elemento e usare la radice del documento come nodo di contesto. Puoi anche usare findvalue invece di findnodes per ottenere il testo del messaggio di errore senza i tag allegati:

my $parser = XML::LibXML->new;
my $doc = $parser->parse_string($xmlString);

my $xpc = XML::LibXML::XPathContext->new($doc);
$xpc->registerNs("x", "http://my.location.com/namespace");

my $error= $xpc->findvalue("x:Tims/x:Error");
print $error, "n";

produzione

Too many entities for operation.  Acceptable limit is 5,000 and 8,609 were passed in.