对于以下XML:
<X12>
<GROUP>
<TS_850>
<REF>
<REF01>CR</REF01>
<REF02>53222</REF02>
</REF>
</TS_850>
</GROUP>
</X12>
此代码有效:
<xsl:variable name="REF02">
<xsl:for-each select="X12/GROUP/TS_850/REF">
<xsl:if test="REF01='CR'">
<xsl:value-of select="REF02"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
...
<xsl:value-of select="$REF02"/>
但是,此代码不会:
<xsl:function name="test:valueWhereValue">
<xsl:param name="context" />
<xsl:param name="conditionalElement" />
<xsl:param name="conditionalValue" />
<xsl:param name="outputElement"/>
<xsl:for-each select="$context">
<xsl:if test="$conditionalElement = $conditionalValue">
<xsl:value-of select="$outputElement" />
</xsl:if>
</xsl:for-each>
</xsl:function>
...
<xsl:copy-of select="test:valueWhereValue(X12/GROUP/TS_850/REF, REF01, 'CR', REF02)"></xsl:copy-of>
我可以说,两个代码片段在功能上应该是等效的。但是,根据我的调试器,REF01和REF02实际上并没有像我期望的那样在函数版本中引用节点。看起来我实际上没有用函数中的for-each语句输入正确的上下文,这会阻止子节点正确选择。为什么会这样,我该如何修复我的功能呢?
答案 0 :(得分:2)
仅供参考,这:
<xsl:variable name="REF02">
<xsl:for-each select="X12/GROUP/TS_850/REF">
<xsl:if test="REF01='CR'">
<xsl:value-of select="REF02"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
- 理论上(*) - 这个:
<xsl:variable name="REF02" select="X12/GROUP/TS_850/REF[REF01 = 'CR']/REF02" />
(*)即每REF01
只有'CR'
等于TS_850
至于你的功能,有三个观察要做:
.
(或current()
)在函数内部表示相同的内容,因为它意味着在外部。您可以使用该事实隐式地传输上下文。<xsl:sequence>
而不是<xsl:value-of>
作为返回值。序列比函数原本返回的普通字符串更通用。所以你的功能看起来更像是这样:
<xsl:function name="test:valueWhereValue">
<xsl:param name="conditionalElement" />
<xsl:param name="conditionalValue" />
<xsl:param name="outputElement"/>
<xsl:if test="$conditionalElement = $conditionalValue">
<xsl:sequence select="$outputElement" />
</xsl:for-each>
</xsl:function>
和这样的电话:
<xsl:template match="X12/GROUP/TS_850/REF">
<xsl:copy-of select="test:valueWhereValue(REF01, 'CR', REF02)" />
</xsl:template>
当你退后一步时,你的功能是一个复杂的替代品:
<xsl:template match="X12/GROUP/TS_850/REF">
<xsl:if test="REF01 = 'CR'">
<xsl:copy-of select="REF02" />
</xsl:if>
</xsl:template>
反过来说这是一种相当复杂的说法:
<xsl:template match="X12/GROUP/TS_850/REF[REF01 = 'CR']">
<xsl:copy-of select="REF02" />
</xsl:template>
其中反过来是一种相当复杂的方式来说 this :
<xsl:copy-of select="X12/GROUP/TS_850/REF[REF01 = 'CR']/REF02" />
所以它首先是一个毫无意义的功能。