2012-05-30 16 views
5

XML:expresión XPath en findnodes() devolver lista de nodos vacío

<zoo xmlns="http://www.zoo.com" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:schemaLocation="http://www.zoo.com employee.xsd"> 

<area id="1" posizione="nord" nome="scimmie"> 
    <animale> 
     <nome>Gigi</nome> 
     <sesso>Male</sesso> 
     <eta>3</eta> 
    </animale> 

    <animale> 
     <nome>Gigia</nome> 
     <sesso>Female</sesso> 
     <eta>2</eta> 
    </animale> 
</area> 

<area id="2" posizione="nord" nome="giraffe"> 
    <animale> 
     <nome>Giro</nome> 
     <sesso>Male</sesso> 
     <eta>6</eta> 
    </animale> 

    <animale> 
     <nome>Gira</nome> 
     <sesso>Female</sesso> 
     <eta>5</eta> 
    </animale> 
</area> 
</zoo> 

código:

my $parser = XML::LibXML->new; 
my $doc = $parser->parse_file("../xml/animals.xml"); 
my $root = $doc->getDocumentElement(); 

my $new_animal = $doc->createElement("animale"); 

my $name_element = $doc->createElement("nome"); 
$name_element->appendTextNode($name); 

my $gender_element = $doc->createElement("sesso"); 
$gender_element->appendTextNode($gender); 

my $age_element = $doc->createElement("eta"); 
$age_element->appendTextNode($age); 

$new_animal->appendChild($name_element); 
$new_animal->appendChild($gender_element); 
$new_animal->appendChild($age_element); 

my $area_element = $root -> findnodes("//area[\@id=$area]")->get_node(1); 

$area_element->appendChild($new_animal); 

zona $ es la identificación de un área (por lo general 1 ahora que estoy probando)

mi propósito es crear un nuevo animal y agregarlo al área adecuada

pero tengo el problema de que la istructio n

my $area_element = $root -> findnodes("//area[\@id=$area]")->get_node(1); 

no funcionará, ya que $ area_element es undef, porque findnodes siempre devuelve una lista de nodos vacío (seleccionado imprimir el tamaño()).

Creo que el problema es la expresión xpath dentro de findnodes, pero no puedo entender lo que está mal, utilizo la misma expresión con otra biblioteca (XML :: XPath) y está funcionando.

¿Qué pasa?

Respuesta

4

El URI para el espacio de nombres deafult en su XML es http://www.zoo.com, por lo que debe especificarlo en sus expresiones XPath para que los nodos sean recogidos.

La forma de hacerlo es declarar un objeto XML::LibXML::XPathContext que asigna un nombre a este espacio de nombres. El nombre puede ser utilizado en expresiones XPath para acceder a los nodos.

Si se escribe

my $xpc = XML::LibXML::XPathContext->new; 
$xpc->registerNs('zoo', 'http://www.zoo.com'); 

ahora tiene un contexto en el que el espacio de nombres predeterminado de XML se denomina zoo. Ahora se puede escribir

my $area_element = $xpc->findnodes("//zoo:area[\@id=$area]", $doc)->get_node(1); 

y encontrará el <area> elemento correcto.

+0

He intentado con su código, pero me sale esto: ---------- Error de software: XPathContext: nodo actual perdido en la línea /Users/toyo/Sites/zoo/cgi-bin/_nuovo_animale.cgi 76 --------- línea 76 es: my $ area_element = $ xpc -> findnodes ("// zoológico: área [\ @ id = $ área]") -> get_node (1); – qwertoyo

+0

@qwertoyo, este es un problema nuevo, y realmente no hay espacio para discutirlo aquí. Haga una nueva pregunta y proporcione el código mínimo ejecutable requerido para demostrar el problema. – ikegami

+0

@qwertoyo, pruebe el más simple: 'my ($ area_element) = $ xpc-> findnodes (" // zoológico: área [\ @ id = $ área] ", $ doc);' – ikegami

-2

La declaración de espacio de nombres es incorrecta, debería decir <zoo xmlns:zoo="http://www.zoo.com" o similar.

+0

'xmlns =" ​​http://www.zoo.com "' sin una ID de espacio de nombres simplemente vincula el espacio de nombres * predeterminado *, es decir, el espacio de nombres para todos los elementos que no llevan un prefijo. Si no hay una definición de espacio de nombres predeterminado, entonces es como si se hubiera utilizado una declaración 'xmlns =" ​​"'. – Borodin

+0

'' y '' son correctos y equivalentes (suponiendo que los niños imiten la falta/presencia del prefijo). El espacio de nombre definido en '' nunca se usa, por lo que su consejo es incorrecto. – ikegami

+0

Respuesta incorrecta. No hay nada de malo en la declaración del espacio de nombres. Downvoting. –

Cuestiones relacionadas