Reputation: 1469
given the following html
<p>
<div class="allpricing">
<p class="priceadorn">
<FONT CLASS="adornmentsText">NOW: </FONT>
<font CLASS="adornmentsText">$1.00</font>
</p>
</div>
</p>
why does
//div[@class="allpricing"]/p[@class="priceadorn"][last()]/font[@class="adornmentsText"][last()]
return the expected value of $1.00
but adding the p
element
//p/div[@class="allpricing"]/p[@class="priceadorn"][last()]/font[@class="adornmentsText"][last()]
returns nothing?
Upvotes: 2
Views: 106
Reputation: 163342
You describe your source as an HTML rather than an XML document, but you haven't explained how you parsed it. If you parse it using an HTML parser, the parser will "repair" it to turn it into valid HTML, which means that the tree it constructs doesn't directly reflect what you wrote in the source. XPath sees this "repaired" tree, not the original.
Upvotes: 0
Reputation: 243479
XPath is case-sensitive.
None of the provided XPath expressions selects any node, because in the provided XML document there is no font
element with an attribute named class
(the element font
has a CLASS
attribute and this is different from having a class
attribute due to the different capitalization).
Due to the same reason, font
and FONT
are elements with different names.
These two XPath expressions, when evaluated against the provided XML document, produce the same wanted result:
//div[@class="allpricing"]
/p[@class="priceadorn"]
[last()]
/font[@CLASS="adornmentsText"]
[last()]
and
//p/div[@class="allpricing"]
/p[@class="priceadorn"]
[last()]
/font[@CLASS="adornmentsText"]
[last()]
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="/">
<xsl:copy-of select=
'//div[@class="allpricing"]
/p[@class="priceadorn"]
[last()]
/font[@CLASS="adornmentsText"]
[last()]'/>
=============
<xsl:copy-of select=
'//p/div[@class="allpricing"]
/p[@class="priceadorn"]
[last()]
/font[@CLASS="adornmentsText"]
[last()]
'/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<p>
<div class="allpricing">
<p class="priceadorn">
<FONT CLASS="adornmentsText">NOW: </FONT>
<font CLASS="adornmentsText">$1.00</font>
</p>
</div>
</p>
the two expressions are evaluated and the results of this evaluation are copied to the output:
<font CLASS="adornmentsText">$1.00</font>
=============
<font CLASS="adornmentsText">$1.00</font>
Upvotes: 0
Reputation: 912
I've often found that fixing the cases was the culprit. XPath 1.0 is case sensitive and unless you take care of the mixed cases explicitly, it will fail in a lot of cases.
Upvotes: 0
Reputation: 241918
You cannot place a div
inside a p
. The div
start closes the p
automatically. See
Nesting block level elements inside the <p> tag... right or wrong?
Upvotes: 3