假设我有以下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'])"/>
答案 0 :(得分:4)
position()
为您提供"current node list"中当前节点的位置,即最近for-each
或apply-templates
选择的任何节点列表。您可以非正式地将其视为for-each
1 的当前迭代次数。通过说
<xsl:for-each select="jobs/job">
当前节点列表是 all 作业元素,因此第一个位置为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
。它可以选择并行或乱序处理不同的节点,只要它以一种与顺序循环产生的相同的方式组装输出即可。
答案 1 :(得分:0)
除了Ian Roberts的好答案:如果您必须将上下文设为job
(无论出于何种原因),您还可以使用xsl:number
代替position()
。
示例:
<xsl:value-of select="PositionTitle"/> - <xsl:number count="job[InternalOrExternal='External']"/><br />