2012-06-22 10 views
5

Sto cercando di analizzare i file XML usando Nokogiri, Ruby e XPath. Io di solito non nascere difficoltà ma con la seguente non posso fare alcuna richiesta XPath:XPath in Nokogiri restituisce array vuoto [] mentre mi aspetto di avere risultati

doc = Nokogiri::HTML(open("myfile.xml")) 
doc.("//Meta").count 
# result ==> 0 

doc.xpath("//Meta") 
# result ==> [] 

doc.xpath(.).count 
# result => 1 

Qui è una versione semplificata del mio file XML

<Answer xmlns="test:com.test.search" context="hf%3D10%26target%3Dst0" last="0" estimated="false" nmatches="1" nslices="0" nhits="1" start="0"> 
    <time> 
    ... 
    </time> 
    <promoted> 
    ... 
    </promoted> 
    <hits> 
    <Hit url="http://www.test.com/" source="test" collapsed="false" preferred="false" score="1254772" sort="0" mask="272" contentFp="4294967295" did="1287" slice="1"> 
     <groups> 
     ... 
     </groups> 
     <metas> 
     <Meta name="enligne"> 
      <MetaString name="value"> 
      </MetaString> 
     </Meta> 

     <Meta name="language"> 
      <MetaString name="value"> 
      fr 
      </MetaString> 
     </Meta> 
     <Meta name="text"> 
      <MetaText name="value"> 
      <TextSeg highlighted="false" highlightClass="0"> 
       La 
      </TextSeg> 
      </MetaText> 
     </Meta> 
     </metas> 
    </Hit> 
    </hits> 
    <keywords> 
    ... 
    </keywords> 
    <groups> 
    ... 
    </groups> 

Come può Ottengo tutti i bambini di <Hit> da questo XML?

+1

Ciò che altri hanno detto, ma anche Nokogiri :: HTML sarà in minuscolo i nomi dei tag. Vuoi Nokogiri :: XML invece – pguardiario

risposta

16

includere le informazioni di spazio dei nomi quando si chiama xpath:

doc.xpath("//x:Meta", "x" => "test:com.test.search") 
+9

in alternativa puoi chiamare 'doc.remove_namespaces!' –

1

Questa è una delle domande più frequenti su XPAth: cerca "spazio dei nomi predefinito XPath".

Se non v'è alcun modo per registrare uno spazio dei nomi per lo spazio dei nomi di default e utilizzare il prefisso registrato (diciamo "x" in //x:Meta) quindi utilizzare:

//*[name() = 'Meta` and namespace-uri()='test:com.test.search'] 

Se è noto che Meta può appartenere solo al default spazio dei nomi, quindi quanto sopra può essere abbreviato in:

//*[name() = 'Meta`] 
Problemi correlati