Иван Бишевац
Иван Бишевац

Reputation: 14641

Select element by contents using CSS or XPath

How to get link with text "Next" in the code bellow using CSS or XPath?

<div id="pagination">
    <a href="link">2</a>
    <a href="link">3</a>
    <a href="link">4</a>
    <a href="link">5</a>
    <a href="link">6</a>
    <a href="link">7</a>
    <a href="link">8</a>
    <a href="link">9</a>
    <a href="link">10</a>
    <a href="link">Next</a>
    <a href="link">Last</a>
</div>

Upvotes: 0

Views: 650

Answers (4)

BeniBela
BeniBela

Reputation: 16917

Actually, it is also possible to do this with css:

 #pagination a:nth-last-child(2)

assuming it is always the 2nd last, and you can use css 3 selectors

Upvotes: 0

the Tin Man
the Tin Man

Reputation: 160551

It's not quite clear what you want. If you want the tenth link:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<div id="pagination">
    <a href="link">2</a>
    <a href="link">3</a>
    <a href="link">4</a>
    <a href="link">5</a>
    <a href="link">6</a>
    <a href="link">7</a>
    <a href="link">8</a>
    <a href="link">9</a>
    <a href="link">10</a>
    <a href="link">Next</a>
    <a href="link">Last</a>
</div>
EOT

doc.search('a')[9]
=> #<Nokogiri::XML::Element:0x80763880 name="a" attributes=[#<Nokogiri::XML::Attr:0x80763498 name="href" value="link">] children=[#<Nokogiri::XML::Text:0x80762fd4 "Next">]>

Or:

doc.at('//a[9]')

If you don't know which element number it'll be but are keying off the text and want to use CSS, I'd do:

doc.search('a').select{ |n| n.content == 'Next' }.first

Unfortunately, CSS can't search the text of a tag, so you have to get a bit creative. XPath can do it:

doc.at('//a[text()="Next"]')

Upvotes: 2

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243459

If the rule is that the a whose string value is "Next" is the last-but one child of div, just use:

//div[@id='pagination']/a[last()-1]

Here we suppose that at most one div exists in the XML document whose id attribute has the value of "pagination" -- this is a fair assumption with XHTML documents.

XSLT - based verification:

<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="node()|@*">
     <xsl:copy-of select="//div[@id='pagination']/a[last()-1]"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<div id="pagination">
    <a href="link">2</a>
    <a href="link">3</a>
    <a href="link">4</a>
    <a href="link">5</a>
    <a href="link">6</a>
    <a href="link">7</a>
    <a href="link">8</a>
    <a href="link">9</a>
    <a href="link">10</a>
    <a href="link">Next</a>
    <a href="link">Last</a>
</div>

the XPath expression is evaluated and the selected node from this evaluation is copied to the output:

<a href="link">Next</a>

Upvotes: 0

Prasanth
Prasanth

Reputation: 5258

path = "/a[.='Next']"

do query for that path, you will get a element with 'Next' as it's text().

Upvotes: 1

Related Questions