2009-11-15 7 views
23

Sto utilizzando Nokogiri :: XML per analizzare le risposte da Amazon SimpleDB. La risposta è qualcosa di simile:Perché non Nokogiri xpath come dichiarazioni xmlns

<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> 

Se solo consegni la risposta subito verso Nokogiri, tutte le query XPath (ad esempio doc/"//Item/Attribute[Name='Foo']/Value") restituisce un array vuoto. Ma se rimuovo l'attributo xmlns dal tag SelectResponse, funziona perfettamente.

C'è qualche cosa in più che devo fare per tenere conto della dichiarazione dello spazio dei nomi? Questa soluzione alternativa è orribile come un trucco.

risposta

32

Quella query XPath cerca elementi che non si trovano in alcun spazio dei nomi. È necessario informare il processore XPath che siete alla ricerca di elementi in namespace http://sdb.amazonaws.com/doc/2007-11-07/

Un modo per farlo con nokogiri è questo:

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

che è riparato. Grazie. –

+8

Fornire semplicemente "** xmlns: **" come 'doc.xpath ('// xmlns: Item ...' dovrebbe funzionare anche – user569825

20

ho trovato davvero utile per capire cosa sta succedendo: http://tenderlovemaking.com/2009/04/23/namespaces-in-xml.html

Fondamentalmente se si dispone di uno spazio dei nomi definito (tramite xmlns=), è necessario utilizzare uno spazio dei nomi nelle ricerche xpath.

Quindi nel tuo caso, si potrebbe fare una delle tre cose:

  • Rimuovere l'attributo xmlns dalla radice SearchResponse. In tal caso, la tua query xpath originale, senza spazi dei nomi funzionerà.
  • utilizza lo spazio di default nella query XPath doc/"//xmlns:Item/xmlns:Attribute[xmlns:Name='Foo']/xmlns:Value"
  • Definire uno spazio dei nomi personalizzato nel secondo argomento della chiamata al metodo xpath e l'uso che nella query, come mostrato in soluzione di hrnt sopra
+4

C'è un metodo 'remove_namespaces!' [Documentato qui] (http: // nokogiri .org/Nokogiri/XML/Document.html # method-i-remove_namespaces% 21). – RobinGower

+1

@RobinGower Sì, e dice 'Per maggiori informazioni sul motivo per cui probabilmente non è una cosa buona in generale, per favore indirizza il browser a ' [tenderlovemaking.com/2009/04/23/namespaces-in-xml/](http://tenderlovemaking.com/2009/04/23/namespaces-in-xml) – nurettin

+0

Entrambi i link nei commenti non sono aggiornati. un collegamento doc aggiornato per [remove_namespaces!] (http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document:remove_namespaces!) – Jason