枚举XSLT节点列表中的项目

时间:2017-07-19 18:28:20

标签: xml xslt xslt-1.0

我有一些像这样的xml:

<people>
    <person id="7" name="Arthur">
    <person id="82" name="Lancelot">
    <person id="14" name="Guinevere">
</people>

在我的XSLT中,在上下文迭代通过此节点集,我希望能够确定具有给定id的节点的位置<people>代码。

因此,例如,我有一个id 82。我希望能够输出2,因为Lancelot的ID为82,是列表中的第二项。

约束:

  • 我仅限于XSLT 1.0
  • 我仅限于单个XSLT转换。所以我不能简单地通过添加position属性来转换上面的XML,然后再运行一个转换来获得我的结果。

XSLT:

<xsl:variable name="idToCheck" select="'82'" />
<xsl:variable name="positionOfPerson" select="/people/person[*work-your-magic-here*]" />

XSLT不需要看起来那样。如果有使用<xsl:key>的解决方案或要求变量中的循环,或其他类似的东西,

3 个答案:

答案 0 :(得分:1)

我发现在preceding中使用preceding-sibling / count()轴有时会比使用xsl:number之类的东西慢一些来进行计数。

示例...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:param name="idToCheck" select="'82'"/>

  <xsl:template match="/people">
    <xsl:variable name="positionOfPerson">
      <xsl:apply-templates select="person[@id=$idToCheck]" mode="pos"/>
    </xsl:variable>
    <xsl:value-of select="$positionOfPerson"/>
  </xsl:template>

  <xsl:template match="*" mode="pos">
    <xsl:number/>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

正如经常发生的那样,当我在输入问题时,我发现了解决方案。我想我会把它发布在这里,以帮助其他可能遇到类似问题的人。

您只需要找到与您的ID匹配的节点,然后使用preceding-sibling计算它之前的所有节点。加1,你就有了自己的位置。

<xsl:variable name="positionOfPerson" select="count(/people/person[@id = $idToCheck]/preceding-sibling::*) + 1" />
<xsl:value-of select="$positionOfPerson" />

输出:

2

答案 2 :(得分:0)

我会做这样的事情:

在列表中递归迭代,直到找到要搜索的元素。 使用参数作为您当前正在迭代的位置

<xsl:variable name="idToCheck" select="'82'" />
<xsl:variable name="position">
<xsl:call-tamplate name="getPos">
<xsl:with-param name="pList" select="insert-parent-node-selector"/>
<xsl:with-param name="pElement" select="insert-specific-person-node-selector"/>
</xsl:call-template>
</xsl:variable>

<xsl:template name="getPos">
<xsl:param name="pElement" select="."/>
<xsl:param name="pList"/>
<xsl:param name="pNumber">1</xsl:param>


<xsl:choose>
<xsl:when test="pElement = pList[1]">
<xsl:value-of slect="pNumber">
</xsl:when>
<xsl:otherwise>
<xsl:call-tamplate name="getPos">
<xsl:with-param name="pList" select="pList[position() > 1]"/>
<xsl:with-param name="pElement"pElement"/>
<xsl:with-param name="pNumber"pNumber + 1"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>

</xsl:template>