2011-05-21 16 views
10

Estoy tratando de usar Nokogiri para mostrar los resultados de una URL. (esencialmente raspando una URL).Obtener todos los elementos por coincidencia parcial del atributo de clase

que tienen algo de HTML que es similar a:

<p class="mattFacer">Matty</p> 
<p class="mattSmith">Matthew</p> 
<p class="suzieSmith">Suzie</p> 

así que tengo que encontrar a continuación, todos los elementos que comienzan con la palabra "mate". Lo que tengo que hacer es guardar el valor del elemento y el nombre del elemento para que pueda hacer referencia a ella la próxima vez .. así que necesito para capturar

"Matty" and "<p class='mattFacer'>" 
"Matthew" and "<p class='mattSmith'>" 

No he trabajado la manera de capturar el elemento HTML, pero esto es lo que tengo hasta ahora para el elemento (no trabaja!)

doc = Nokogiri::HTML(open(url)) 
tmp = "" 
doc.xpath("[class*=matt").each do |item| 
    tmp += item.text 
end 

@testy2 = tmp 
+0

Buena pregunta, +1. Vea mi respuesta para una solución completa, corta y fácil de una línea de expresión XPath. :) –

+0

¿Alguien ve los rieles aquí? – Nakilon

Respuesta

15

Esto debería empezar:

doc.xpath('//p[starts-with(@class, "matt")]').each do |el| 
    p [el.attributes['class'].value, el.children[0].text] 
end 
["mattFacer", "Matty"] 
["mattSmith", "Matthew"] 
+0

sí, eso parece hacer el truco! ¡Gracias! ¿Hay algún método para buscar cualquier parte del nombre de la clase? Entonces, si fuera

¿cómo buscaría? Básicamente puede ser cualquier cosa, ¡pero quiero atrapar la parte mate! gracias por su ayuda aquí :) –

+5

XPath tiene muchas funciones como 'starts-with', p. 'contiene' y' subcadena'. http://www.w3.org/TR/xpath/#corelib –

+0

excelente - ¡gracias!Utilicé contain() para combinar - ¡perfecto! –

2

Uso:

/*/p[starts-with(@class, 'matt')] | /*/p[starts-with(@class, 'matt')]/text() 

Esta selecciona ningún p elementos que es un hijo del elemento superior del documento XML y el valor de cuya class atributo comienza con "matt" y cualquier niño texto-nodo de cualquiera de tales p elemento.

Cuando evaluaron contra este documento XML (se proporcionó ninguno!):

<html> 
    <p class="mattFacer">Matty</p> 
    <p class="mattSmith">Matthew</p> 
    <p class="suzieSmith">Suzie</p> 
</html> 

los siguientes nodos se seleccionan (cada uno en una línea separada) y se puede acceder por posición:

<p class="mattFacer">Matty</p> 
Matty 
<p class="mattSmith">Matthew</p> 
Matthew 

Aquí está una verificación rápida XSLT:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:for-each select= 
    "/*/p[starts-with(@class, 'matt')] 
    | 
    /*/p[starts-with(@class, 'matt')]/text() 
    "> 
    <xsl:copy-of select="."/> 
    <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

El resultado de esta transformación, cuando se aplica en el documento mismo XML (arriba) es la espera, correcta secuencia de nodos seleccionados:

<p class="mattFacer">Matty</p> 
Matty 
<p class="mattSmith">Matthew</p> 
Matthew 
0

la respuesta aceptada es grande, pero otro enfoque ser el uso de Nikkou, lo que le permite adaptar a través de expresiones regulares (sin necesidad de estar familiarizado con las funciones XPath):

doc.attr_matches('class', /^matt/).collect do |item| 
    [item.attributes['class'].value, item.text] 
end 
0
doc = Nokogiri::HTML(open(url)) 
tmp = "" 
items = doc.css("p[class*=matt]").map(&:text).join 
+1

typo 'css (" p [clase * = mate] ")' – hlcs

Cuestiones relacionadas