XSLT for-each,其中position()= 1

时间:2013-11-23 19:31:38

标签: xslt xpath foreach xslt-1.0

如果我有一个到NodeSet的XPath - 我理解以下XSLT将遍历与提供的XPath匹配的每个节点。和“价值”功能,匹配“。”应该返回每个匹配节点的数据。

<xsl:for-each select="//some/X-Path/Here/*">
<xsl:value-of select="." />
</xsl:for-each">

如果我有一个xpath到单个元素怎么办?突然在单个节点上做“for-each”似乎很傻。但我在XSLT中找不到可比较的“功能”来完成相同的行为 - 但是输入只是一个元素,而不是集合。

<xsl:match select="//some/X-Path/Here[1]">
<xsl:value-of select="." />
</xsl:match">

或者这种效果。我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:3)

嗯,你基本上自己回答了你的问题。迭代一个大小为1的节点集可能看起来有点奇怪,但还有其他方法可以做到这一点。一个是按照您的建议创建一个匹配模板,并通过<apply-templates>调用它。另一种方法是直接插入值@halfbit建议。恕我直言,很难说什么是最好的方法。这绝对取决于具体情况。

然而,与使用<for-each>相比,可能还有两个赞成<value-of>的想法。

  • 前者仅在表达式存在时执行,而后者始终执行。当然,这对于<value-of>部分来说并不坏,因为它应该是emtpty,但如果它被包装器包围可能会使你的输出搞乱,那么这可能是不方便的。所以换句话说就是

    ...
    <xsl:for-each select="//some/X-Path/Here/*">
      output something here
      <xsl:value-of select="." />
      output something here
    </xsl:for-each"> 
    ...
    

    具有块的隐式if条件,另一方面是构造

    ...
    output something here
    <xsl:value-of select="//some/X-Path/Here/*" />
    output something here
    ...
    

    没有。所以,你必须用<if>然后围绕它:

    ...
    <xsl:if test="//some/X-Path/Here/*">
      output something here
      <xsl:value-of select="//some/X-Path/Here/*" />
      output something here
    <xsl:if>
    ...
    
  • 另一件事是<for-each>标记更改了上下文节点,如果您想要访问XPath路径中的元素以外的元素,这可能很方便。所以,例如,

    ...
    <xsl:for-each select="//some/X-Path/Here/*">
      <xsl:value-of select="@attr1" />
      <xsl:value-of select="@attr2" />
      <xsl:value-of select="@attr3" />
      ...
      <xsl:value-of select="@attrN" />
    </xsl:for-each"> 
    ...
    

    简短(并且可能更容易阅读)
    ...
    <xsl:if test="//some/X-Path/Here/*">
      <xsl:value-of select="//some/X-Path/Here/*/@attr1" />
      <xsl:value-of select="//some/X-Path/Here/*/@attr2" />
      <xsl:value-of select="//some/X-Path/Here/*/@attr3" />
      ...
      <xsl:value-of select="//some/X-Path/Here/*/@attrN" />
    <xsl:if>
    ...
    

    特别是如果你有一个冗长的XPath表达式。