1

假设我有以下 xml 文件:

<jobs>
  <job>
    <PositionTitle>Painter</PositionTitle>
    <InternalOrExternal>External</InternalOrExternal>
  </job>
  <job>
    <PositionTitle>Plumber</PositionTitle>
    <InternalOrExternal>Internal</InternalOrExternal>
  </job>
  <job>
    <PositionTitle>Chemist</PositionTitle>
    <InternalOrExternal>Internal</InternalOrExternal>
  </job>
  <job>
    <PositionTitle>Teacher</PositionTitle>
    <InternalOrExternal>External</InternalOrExternal>
  </job>
</jobs> 

.

我使用以下 xslt 处理它以仅显示外部作业:

<?xml version="1.0" encoding="UTF-8"?>
 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:content="http://purl.org/rss/1.0/modules/content/" >
  <xsl:output method="html"/>
  <xsl:template match="/">

        <xsl:for-each select="jobs/job">

            <xsl:if test="InternalOrExternal = 'External'"><!-- Only show external jobs -->
              <xsl:value-of select="PositionTitle"/> - <xsl:value-of select="position()"/><br />
            </xsl:if>

        </xsl:for-each>

 </xsl:template>
 </xsl:stylesheet>

结果如下:

Painter - 1
Teacher - 4

我假设 position() 函数返回 xml 文件中的实际位置,并且不考虑任何可能排除某些工作的 if 语句。在这种情况下,内部职位被排除在外,但他们的职位仍然被计算在内。

我想要的结果是:

Painter - 1
Teacher - 2

他们有什么方法可以让 position() 函数只计算我显示的内容吗?

我试过这个没有运气:

<xsl:value-of select="position(jobs/job[InternalOrExternal='External'])"/>
4

2 回答 2

4

position()为您提供当前节点在“当前节点列表”中的位置,即最近for-each或选择的任何节点列表apply-templatesfor-each您可以非正式地将其视为1的当前迭代次数。通过说

<xsl:for-each select="jobs/job">

当前节点列表是所有作业元素,因此第一个节点的位置为 1,第四个节点的位置为 4。如果您删除xsl:if并将过滤移动到for-each选择器上的谓词中:

<xsl:for-each select="jobs/job[InternalOrExternal='External']">
  <xsl:value-of select="PositionTitle"/> - <xsl:value-of select="position()"/><br />
</xsl:for-each>

那么当前节点列表仅包含“外部”job元素,您将获得所需的position()值。


1由于 XSLT 指令没有副作用(例如,没有可更新的变量),XSLT 处理器不必在for-each内部使用顺序循环来实现。它可以选择并行或乱序处理不同的节点,只要它以一种看起来与顺序循环产生的相同的方式组合输出即可。

于 2013-11-01T11:06:42.150 回答
0

除了 Ian Roberts 的出色回答:如果您必须拥有上下文job(无论出于何种原因),您也可以使用xsl:number代替position().

例子:

<xsl:value-of select="PositionTitle"/> - <xsl:number count="job[InternalOrExternal='External']"/><br />
于 2013-11-01T16:20:19.140 回答