tags:

views:

35

answers:

1

Can anyone help with the following XPath question? Given the node-set:

<table> 
  <rows>
    <row>
      <value column="Product">Coal</value>
      <value column="Quantity">10000</value>
    </row>
    <row>
      <value column="Product">Iron</value>
      <value column="Quantity">5000</value>
    </row>
    <row>
      <value column="Product">Ore</value>
      <value column="Quantity">4000</value>
    </row>
  </rows>
</table>

I want to query to find the node sub-set with a given product name. Note that the product name is being supplied by an attribute of the current node being processed (i.e. "@name"). So when the @name attribute has the value of "Coal" I would expect this to be returned:

<row>
  <value column="Product">Coal</value>
  <value column="Quantity">10000</value>
</row>

This is what I've come up with; I know it's wrong, because I don't get anything back.

$table/rows/row[value[@column='Product'][text()=@name]]

</code>

+1  A: 

You are obviously missing the current() function

$table/rows/row[value[@column='Product'] = current()/@name]

Within an XPath predicate (i.e. within square brackets) the context node is the node the predicate is applied to.

In your case, when you say $table/rows/row[x=@name], then @name refers to the @name attribute of row. Which has no @name attribute, so the predicate always evaluates to false for all nodes.

current() returns the current XSLT context node to help in exactly this case.

Tomalak
Perfect, thanks Tomalak. I came up with a work-around by copying the @name attribute out to a variable first, but yours is much nicer.
gerrod
I don't think that you need current(), maybe I am wrong, but isn't current() the same as '.'?
vtd-xml-author
@vtd: Yes, you are wrong. If `current()` were the same as `.`, then `current()` would not exist. ;)
Tomalak
when would they not be equal then?
vtd-xml-author
@vtd: Outside of an XPath predicate.
Tomalak