tags:

views:

35

answers:

3

I cant really formulate that better, so I'll go with an example instead:

XML:

<root>
  <foo>
    <bar id="1">sdf</bar>
    <bar id="2">sdooo</bar
  </foo>
  <feng>
    <heppa id="4">hihi</heppa>
    <heppa id="2">sseeapeea</heppa>
    <heppa id="1">....</heppa>
  </feng>
</root>

XSLT:

<xsl:for-each select="/root/foo/bar">
  <p>
    <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = @id]" />
  </p>
</xsl:for-each>

Desired output:

<p>sdf: ....</p>
<p>sdooo: sseeapeea</p>

Actual output:

<p>sdf: hihi</p>
<p>sdooo: hihi</p>
+2  A: 

I assume you mean /root/foo/bar since /root/foo elements don't have id.

You're comparing the @id with itself, so of course it's true for the first node examined. You can use current() to reference the current node in an expression:

<xsl:for-each select="/root/foo/bar">
  <p>
    <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = current()/@id]" />
  </p>
</xsl:for-each>
Jon Hanna
Yes, ofc! Thank you for the correction. :)And thanks a lot for the solution! :D
Lilleman
+1  A: 

Another solution is to read the id attribute into a variable.

<xsl:for-each select="/root/foo/bar">
    <xsl:variable name="id" select="@id"/>
    <p>
        <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = $id]" />
    </p>
</xsl:for-each>

This might be handier, if your real use case is more complicated and you need to use the value of the id multiple times in this for-each section.

jasso
Very good, didnt think of that one. Thank you!
Lilleman
+2  A: 

For selecting nodes with XPath 1.0 only, you need to do a node set comparison:

/root/feng/heppa[@id=/root/foo/bar/@id]

Of course, this has NxM complexity (as the others XSLT solutions)

With XSLT 1.0 you should use keys because there are cross references:

<xsl:key name="kBarById" select="bar" use="@id"/>

<xsl:template match="/root/feng/heppa[key('kBarById',@id)]">       
    <p>       
        <xsl:value-of select="concat(key('kBarById',@id),': ',.)"/>
    </p>       
</xsl:template> 
Alejandro
+1 for the `key` solution!
Dimitre Novatchev
+1 for good solution. `Of course, this has NxM complexity`: that depends on the processor. key() is a hint to the processor on how to optimize. Processors can be very smart, such that a stylesheet without key() might be processed as efficiently as with key() (or in other words, a key is inferred). But agreed that an explicit key() solution is more likely to be efficient.
LarsH
@LarsH: I think that inferred keys are a shoot in the dark... Node set comparison are more likely supposed to be optimized (breaking the iteration on first success) but it would never be a linear N complexity, I think.
Alejandro
@Alejandro: I agree it's a shot in the dark, unless you know details about your XSLT processor... Mr. Kay has written a lot about Saxon optimization, so you can depend on some things. My point though was that in theory, one can't guarantee that the initial XPath expression has NxM complexity, nor that the stylesheet with explicit keys has linear complexity. Those depend on the processor implementation.
LarsH
Good one! Thanks!
Lilleman
@Lilleman: You are wellcome!
Alejandro