假设,我确实有一个 MyObject 元素数组,该数组具有一些属性,例如 IsFinalResult ,我想根据此属性有选择地选择项目。 我希望该逻辑仅从数组中获取 first 元素,该元素匹配给定条件 IsFinalResult == true (即使乘法元素匹配条件)。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="ArrayOfMyObject/MyObject">
<xsl:choose>
<xsl:when test="// Here how to check?">
// this will match only once
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我只能使用XPath 1.0来做到这一点。
答案 0 :(得分:1)
您可以使用position()
函数
<xsl:when test="position() = 1 and IsFinalResult='true'">
// this will match only once
</xsl:when>
但是还有其他方法可以处理这种情况。
其中之一是对谓词使用模板匹配:
<xsl:template match="/ArrayOfMyObject/MyObject[IsFinalResult = 'true' and position() = 1]">
<!-- For the first MyObject element -->
...
和
<xsl:template match="/ArrayOfMyObject/MyObject[IsFinalResult = 'true' and position() > 1]">
<!-- For all the other MyObject elements -->
...
受以下评论的启发,还有另一种方式来阅读您的问题(我在此答案的先前版本中曾有过)。这种方式可以通过使用两个单独的条件来实现:
<xsl:for-each select="ArrayOfMyObject/MyObject[IsFinalResult='true']">
<xsl:choose>
<xsl:when test="position() = 1">
// this will match only once
</xsl:when>
...
第二种方式更改如下:
<xsl:template match="/ArrayOfMyObject/MyObject[IsFinalResult = 'true'][1]">
<!-- Matches the first element of the list of elements that satisfy the first predicate -->
...
这里[1]
不是必需的-考虑将其视为强调可读性的一种方法。
还有
<xsl:template match="/ArrayOfMyObject/MyObject[IsFinalResult = 'true'][position() > 1]">
<!-- Matches all the other elements of the list of elements that satisfy the first predicate -->
...
答案 1 :(得分:0)
考虑使用模板方法...
<xsl:template match="/">
<xsl:apply-templates select="ArrayOfMyObject/MyObject" />
</xsl:template>
然后,为了表示您的xsl:when
测试,以匹配第一个“ IsFinalResult ='true'”元素,则模板匹配应为以下内容……
<xsl:template match="MyObject[@IsFinalResult='true'][1]">
(注意,我假设IsFinalResult
是此处的属性。如果不是,只需删除@
前缀)
要代表您的xsl:otherwise
,请使用一个模板(优先级较低),该模板将提取所有其他MyObject
元素
<xsl:template match="MyObject">
因此,鉴于以下XML:
<ArrayOfMyObject>
<MyObject IsFinalResult="false">1</MyObject>
<MyObject IsFinalResult="false">2</MyObject>
<MyObject IsFinalResult="true">3</MyObject>
<MyObject IsFinalResult="false">4</MyObject>
<MyObject IsFinalResult="true">5</MyObject>
<MyObject IsFinalResult="true">6</MyObject>
</ArrayOfMyObject>
如果您应用此XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="ArrayOfMyObject/MyObject" />
</xsl:template>
<xsl:template match="MyObject[@IsFinalResult='true'][1]">
<When>
<xsl:value-of select="." />
</When>
</xsl:template>
<xsl:template match="MyObject">
<Otherwise>
<xsl:value-of select="." />
</Otherwise>
</xsl:template>
</xsl:stylesheet>
输出是这个...
<Otherwise>1</Otherwise>
<Otherwise>2</Otherwise>
<When>3</When>
<Otherwise>4</Otherwise>
<Otherwise>5</Otherwise>
<Otherwise>6</Otherwise>
(如果仅考虑将<xsl:template match="MyObject[@IsFinalResult='true' and position() = 1]">
作为模板的第一个子元素,则将模板匹配项更改为@IsFinalResult='true'
。
请注意,如果只希望xsl:otherwise
处理IsFinalResult="true"
(在第一个之后)中的元素,则只需添加第三个模板即可忽略其他元素
<xsl:template match="MyObject[not(@IsFinalResult='true')]" />