tags:

views:

74

answers:

3

Hello,

I'm using a Java application based on Saxon for the XPath parser. Please consider the following:

<import>  
  <record ref="abc">  
    <id>123</id>  
    <data>Value<data>  
  </record>  
  <record ref="def">  
    <parent>123</parent>  
    <data>Value2</data>  
  </record> 
</import> 

My use case is, I'm looping through the record nodes and need to look up another with attribute ref equal to the value under the child parent node.

If the current node is <record ref="def">, how can I write a query to return the data node within the first record node by matching on /query/record/id/text() = current node/parent/text() ?

If I execute this query:

/import/record[id/text() = '123']/data

Then I get the correct data node, but I can't seem able to replace '123' for the value under the parent node?

I've tried replacing '123' with ./parent/text() and while the XPath compiles, no results are returned.

Thanks,

JB

A: 

The period is used to refer to the current node. However you have a flaw in your logic: What your path

/import/record[id/text() = ./parent/text()]/data

defines is a <record> that has a parent and a id child which must have the same content.

musiKk
Right, so how can I refer to the current node (<record ref="def">, the one I pass into the XPath evaluate method), so I can use the value under parent?
Got it! /import/record[id = /import/record[position()]/parent]/data
+1  A: 

With the period you are referencing a node in the path context, you should be able to use variables to fix your problem:

<xsl:template match="/import/record[@parent]">
    <xsl:variable name="pid" select="./parent/text()" />
    <xsl:for-each select="/import/record[id/text() = $pid">
        <!-- actions -->
    </xsl:for-each>
</xsl:template>

edit

You might get away with something like the following single xpath expression:

/import/record[id/text() = /import/record/parent/text()]/data

(select those records that are referenced by others)

rsp
I really appreciate the time you've taken to write that out, but I'm not using XLST. I'm using straight XPath against a DOM.
Can you use the same approach from code, or does it have to be in one single path expression?
rsp
One single expression. I see XLST has current, but there appears to be no provision when parsing a DOM - see the list of functions: http://www.saxonica.com/documentation/functions/intro.html
I guess I could write my own function to provide current() but this seems so obvious that it should be available in the Saxon/XPath API.
A: 

For some reason, current() exists in XSLT but not for XPath against a DOM. You can hard code something like this:

/import/record[id = /import/record[position()]/parent]/data

Actually, I'm not sure that works :-)