如果元素

时间:2018-05-28 11:53:14

标签: xml xslt

我正在尝试从一个字段插入一个值,如果具有相同父项的另一个字段具有特定值。

<xsl:if test="s0:PRILoop1/s0:PRI/s0:C509/C50901='AAB'">
                  <UnitPrice>
                    <xsl:value-of select="../C50902"/>
                  </UnitPrice>
                </xsl:if>

如果C50901 ='AAB',则应将C50902中的值插入UnitPrice。我假设在if元素之后,我需要返回一个级别,然后进入兄弟元素以选择它,但在这种情况下没有任何值。

范围是否与if元素不同?我怎样才能看到自己与其他元素的关系?

1 个答案:

答案 0 :(得分:2)

当您在<xsl:template>中需要此路径以获取要检查的元素时:

s0:PRILoop1/s0:PRI/s0:C509/C50901[.='AAB']

...然后你无法在<xsl:if>中使用此路径来获取要插入的元素:

../C50902

那是因为<xsl:if>中的上下文节点仍然保留在树中较高位置的完全相同的位置。你需要一个完整的路径来实现它:

s0:PRILoop1/s0:PRI/s0:C509/C50901[.='AAB']/../C50902

幸运的是,简单地更改上下文节点会更容易,也更合乎逻辑。您可以使用<xsl:for-each>执行此操作(即使只有一个节点到#34;迭代&#34;):

<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>

这是<xsl:if>的两倍。当s0:PRILoop1/s0:PRI/s0:C509[C50901='AAB']不存在时,循环不会运行。

更惯用的是,您将拥有一个单独的模板:

<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" />

当你有多个案例需要照顾时,这是有道理的,效果是一个switch语句。

  

我怎样才能看到自己与其他元素的关系?

上下文节点通常保持不变。想象一下,当上下文节点因为你做<xsl:if test="...">而神奇地成为别的东西时就会出现混乱。

只有非常少的构造可以改变上下文,主要是<xsl:for-each><xsl:apply-templates><xsl:for-each-group>。见List of XSLT instructions/functions that change the context node?