How do I select the last XHTML <span> element with a particular class in XPath?
My target XHTML document (simplified) is like the following:
<html>
<head>
</head>
<body>
<span class="boris"> </span>
<span class="boris"> </span>
<span class="johnson"> </span>
</body>
</html>
I'm trying to select the last of class "boris."
The XPath expression
//span[@class="boris"]
selects all spans of class boris. How do I select the last one of these?
I've tried
//span[@class="boris" and last()]
which doesn't work because last() here refers to the last span in the WHOLE DOCUMENT.
How do I s开发者_高级运维elect all the spans of class boris... and then the last one of these?
I've read 5 or 6 XPath tutorials and done a lot of Googling and I can't find a way to do this in XPath alone :(
Thanks in advance for help :)
(//span[@class="boris"])[last()]
The parens are necessary to make last()
work the way you want. This:
//span[@class="boris"][last()]
is wrong because it would select multiple <span class="boris">
if they were the respective last-of-their-kind within their parents:
<div>
<span class="boris">#1</span><!-- this one -->
</div>
<div>
<span class="boris">#2</span><!-- this one not -->
<span class="boris">#3</span><!-- but this -->
</div>
<div>
<span class="boris">#4</span><!-- and this, too -->
<span class="other">#5</span><!-- this not -->
</div>
The first expression would select only one: #4. This is the one you need.
The second expression selects #1, #3 and #4, as illustrated.
Your try (//span[@class="boris" and last()]
) would select every <span class="boris">
, but mainly because you got it wrong: last()
evaluates to a number. And any number other than 0
evaluates to true
in boolean context. This means the expression can never be false
for a <span class="boris">
.
You must do a proper comparison for boolean: What you meant was
//span[@class="boris" and position() = last()]
which is still wrong, though. It selects #1 and #3, because here both position()
and last()
count within the parent element.
When you use ()
parens you create a new temporary node-set, and last()
can work on that.
Just guessing here, but isn't it //span[@class="boris"][last()]
?
EDIT:
I just saw you can also nest predicates (see here), so maybe you can do: //span[@class="boris"[last()]]
EDIT 2:
Nope, that doesn't work. Go with the first one. By the way, I tried your and last()
online, and it seemed to do what you wanted. Huh.
精彩评论