When you need this path in your <xsl:template>
to get to the element you want to check:
s0:PRILoop1/s0:PRI/s0:C509/C50901[.='AAB']
...then you cannot use this path in your <xsl:if>
to get to the element you want to insert:
../C50902
That's because the context node in the <xsl:if>
still remains at the exact same spot higher up in the tree. You would need a full path to get to it:
s0:PRILoop1/s0:PRI/s0:C509/C50901[.='AAB']/../C50902
Luckily it's much easier and more logical to simply change the context node. You can do so with <xsl:for-each>
(even if there is only one node to "iterate"):
<xsl:for-each select="s0:PRILoop1/s0:PRI/s0:C509[C50901='AAB']">
<!-- ...we are at the <s0:C509> element at this point! -->
<UnitPrice>
<xsl:value-of select="C50902"/>
</UnitPrice>
</xsl:for-each>
This doubles as an <xsl:if>
. When s0:PRILoop1/s0:PRI/s0:C509[C50901='AAB']
does not exist, the loop does not run.
More idiomatically you would have a separate template:
<xsl:template match="foo">
<!-- just output that <s0:C509>, the XSLT engine will decide what to do -->
<xsl:apply-templates select="s0:PRILoop1/s0:PRI/s0:C509" />
</xsl:template>
<xsl:template match="s0:C509[C50901='AAB']">
<UnitPrice>
<xsl:value-of select="C50902"/>
</UnitPrice>
</xsl:for-each>
<xsl:template match="s0:C509[C50901='SomethingElse']">
<SomethingElse>
<xsl:value-of select="SomethingElse"/>
</SomethingElse>
</xsl:for-each>
<!-- any <s0:C509> we don't have a template for will be suppressed -->
<xsl:template match="s0:C509" />
This makes sense when you have more than one case to look after, the effect is that of a switch statement.
How can I see where I am in relation to the other elements?
The context node generally stays the same. Imagine the chaos when the context node would magically be something else just because you did an <xsl:if test="...">
.
There are only very few constructs that change the context, mainly <xsl:for-each>
, <xsl:apply-templates>
and <xsl:for-each-group>
. See List of XSLT instructions/functions that change the context node?