Reputation: 1059
I am trying to insert a value from one field, if another field with the same parents has a certain value.
<xsl:if test="s0:PRILoop1/s0:PRI/s0:C509/C50901='AAB'">
<UnitPrice>
<xsl:value-of select="../C50902"/>
</UnitPrice>
</xsl:if>
If C50901='AAB', then the value in C50902 should be inserted into the UnitPrice. I am assuming after the if element, I need to go back one level, and then down into the sibling element to select it, but no value is being carried over in this case.
Does scope work different with if elements? How can I see where I am in relation to the other elements?
Upvotes: 0
Views: 372
Reputation: 338406
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?
Upvotes: 2