2016-03-31 3 views
1

Mit Nokogiri, versuche ich, alle "ersten" Ebene p und ul HTML-Tags und mit ein wenig Schwierigkeit zu erhalten.Wie p- und ul-Tags erfassen, ohne die verschachtelten Tags von ul mit Nokogiri zu erfassen?

Zum Beispiel, hier ist der HTML-Code, ich arbeite mit

<p><strong>Just testing <em>something</em> out&nbsp;</strong>over here.</p> 
<p>Here's a paragraph that contains bullets though:</p> 
<ul> 
    <li>One thing here. 
     <ul> 
      <li>One more thing</li> 
     </ul> 
    </li> 
    <li>Another thing here</li> 
</ul> 
<p> 
    <br> 
</p> 
<ul> 
    <li>nothing</li> 
</ul> 
<p>Some more text.</p> 

Ich bin zu wollen all Absätze ergreifen und alle der ungeordneten Listen. Da die ungeordnete Listen mit dem p Tag nicht umgeben sind, muss ich auch für diejenigen, greifen mit dem folgenden Beispiel:

#data = the HTML above 
html = Nokogiri::HTML(data) 
html.xpath("//p | //ul").each do |p| 
# some code 
end 

Das Problem ist, dass die Ausgabe von html.xpath("//p | //ul") wie folgt aussieht:

<p><strong>Just testing <em>something</em> out </strong>over here.</p> 
<p>Here's a paragraph that contains bullets though:</p> 
<ul> 
    <li>One thing here. 
     <ul> 
      <li>One more thing</li> 
     </ul> 
    </li> 
    <li>Another thing here</li> 
</ul> 
<ul> 
    <li>One more thing</li> 
</ul> 
<p> 
    <br> 
</p> 
<ul> 
    <li>nothing</li> 
</ul> 
<p>Some more text.</p> 

Wie Sie dort sehen können, wiederholt sich One more thing selbst, weil es eines der verschachtelten ul Tags innerhalb von ul ist. Aus diesem Grund endet mein Code zweimal mit diesem Text.

Also, was ich suche ist, um verschachtelte Tags „ausschließen“, wenn sie die gleiche der Eltern ist so, dass, wenn ich html.xpath("//p | //u") oder etwas ähnliches laufen, ist es an der ul Tag sieht und behandelt sie einfach alle als ein Element in das xpath Ausgangsarray

Gibt es eine Möglichkeit, dies mit Nokogiri zu tun?

Antwort

3

Sie können das folgende Muster der ersten Ebene Element bestimmter Namen wählen XPath:

//target_element[not(ancestor::target_element)] 

Also für Ihren speziellen Fall der XPath wie folgt sein würde:

//p[not(ancestor::p)] | //ul[not(ancestor::ul)]