2009-11-15 15 views
23

Estoy utilizando Nokogiri :: XML para analizar las respuestas de Amazon SimpleDB. La respuesta es algo así como:¿Por qué no Nokogiri xpath como xmlns declaraciones

<SelectResponse xmlns="http://sdb.amazonaws.com/doc/2007-11-07/"> 
    <SelectResult> 
    <Item> 
     <Attribute><Name>Foo</Name><Value>42</Value></Attribute> 
     <Attribute><Name>Bar</Name><Value>XYZ</Value></Attribute> 
    </Item> 
    </SelectResult> 
</SelectResponse> 

Si tan solo lado, la respuesta directamente hacia Nokogiri, todas las consultas XPath (por ejemplo doc/"//Item/Attribute[Name='Foo']/Value") devuelven una matriz vacía. Pero si elimino el atributo xmlns de la etiqueta SelectResponse, funciona perfectamente.

¿Hay alguna cosa adicional que deba hacer para dar cuenta de la declaración del espacio de nombres? Esta solución alternativa se siente horriblemente como un truco.

Respuesta

32

Esa consulta XPath busca elementos que no están en ningún espacio de nombres. Es necesario que informe a su procesador de XPath que está buscando elementos de espacio de nombres http://sdb.amazonaws.com/doc/2007-11-07/

Una forma de hacerlo que con nokogiri es la siguiente:

doc = Nokogiri::XML.parse(...) 
doc.xpath("//aws:Item/aws:Attribute[Name='Foo']/aws:Value", {"aws" => "http://sdb.amazonaws.com/doc/2007-11-07/"}) 
+0

que es fija. Gracias. –

+8

Solo debe proporcionar "** xmlns: **" como 'doc.xpath ('// xmlns: Item ...' también debería funcionar. – user569825

20

encontré esto realmente útil para comprender lo que está pasando: http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html

Básicamente si tiene un espacio de nombres definido (a través de xmlns=), debe usar un espacio de nombres en sus búsquedas xpath.

Así, en su caso, se podría hacer una de tres cosas:

  • Retire el atributo xmlns de la raíz SearchResponse. En ese caso, su consulta original xpath, sin espacio de nombres, funcionará.
  • Utilice el espacio de nombres predeterminado en su consulta XPath doc/"//xmlns:Item/xmlns:Attribute[xmlns:Name='Foo']/xmlns:Value"
  • Definir un espacio de nombres personalizado en el segundo argumento de la llamada al método xpath y el uso que en la consulta, como se muestra en la solución de hrnt anterior
+4

Hay un método 'remove_namespaces!' [Documentado aquí] (http: // nokogiri .org/Nokogiri/XML/Document.html # method-i-remove_namespaces% 21). – RobinGower

+1

@RobinGower Sí, y dice 'Para obtener más información sobre por qué esto probablemente no sea bueno en general, por favor dirija su navegador a' [tenderlovemaking.com/2009/04/23/namespaces-in-xml/](http://tenderlovemaking.com/2009/04/23/namespaces-in-xml) – nurettin

+0

Ambos enlaces en los comentarios están desactualizados. Aquí está un enlace de doc actualizado para [remove_namespaces!] (http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document:remove_namespaces) – Jason

Cuestiones relacionadas