【问题标题】:How to get last position in XSLT如何获得 XSLT 中的最后一个位置
【发布时间】:2014-06-29 11:55:00
【问题描述】:

我怎样才能得到最后一个位置

<contrib contrib-type="author" corresp="no">
  <surname>Duan</surname>
</contrib>
<contrib contrib-type="author" corresp="no">
  <surname>Ding</surname>
</contrib>
<contrib contrib-type="author" corresp="no">
  <surname>Li</surname>
</contrib>
<contrib contrib-type="author" corresp="no">
  <surname>Miao</surname>
</contrib>

这是 XSL

<xsl:template match="contrib">
  <xsl:choose>
    <xsl:when test="position()=last()">
      <xsl:apply-templates />
      <xsl:text> and </xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates/>
      <xsl:text>, </xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

我需要这个输出:Duan、Ding、Li 和 Miao

谁能告诉我它有什么问题?提前致谢。

【问题讨论】:

标签: xslt


【解决方案1】:

您已经在使用 last() 函数,但可能认为它不起作用。虽然您没有展示完整的 XSLT,但您可能依赖 XSLT 的内置模板来选择 contrib 元素。在这种情况下,它正在选择 XML 中的节点,而不仅仅是元素,并且 position() 与刚刚选择的节点相关,包括文本节点。最后一个 contrib 元素不是最后一个节点,因为在最后一个元素之后有一个空白节点。

您可以做的是使用 strip-space 命令删除此类空白节点。

试试这个 XSLT

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

    <xsl:template match="contrib">
      <xsl:choose>
        <xsl:when test="position()=last()">
          <xsl:text> and </xsl:text>
        </xsl:when>
        <xsl:when test="position() > 1">
          <xsl:text>, </xsl:text>
        </xsl:when>
      </xsl:choose>
      <xsl:apply-templates />
    </xsl:template>
</xsl:stylesheet>

但是,如果 XML 中有其他元素,这可能不起作用。因此,为了解决这个问题,您可以显式选择 contrib 元素,在这种情况下 position 会选择最后一个。也试试这个 XSLT

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

    <xsl:template match="/*">
      <xsl:apply-templates select="contrib" />
    </xsl:template>

    <xsl:template match="contrib">
      <xsl:choose>
        <xsl:when test="position()=last()">
          <xsl:text> and </xsl:text>
        </xsl:when>
        <xsl:when test="position() > 1">
          <xsl:text>, </xsl:text>
        </xsl:when>
      </xsl:choose>
      <xsl:apply-templates />
    </xsl:template>
</xsl:stylesheet>

【讨论】:

    【解决方案2】:

    您的代码在适当的上下文中工作(添加根模板)函数position() 没有它就无法工作。

    检查一下:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="/"> 
    <contribs>
    <xsl:apply-templates/>
    </contribs>
    </xsl:template>
    
    <!-- your template -->
    
    <xsl:template match="contrib">
      <xsl:choose>
        <xsl:when test="position()=last()">
          <xsl:apply-templates />
          <xsl:text> and </xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates/>
          <xsl:text>, </xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    
    </xsl:stylesheet>
    

    您还必须方便地包装您的 xml 数据(多根 xml 不正确)

    <?xml version="1.0" encoding="UTF-8"?>
    
    <doc>
    
    <contrib contrib-type="author" corresp="no">
      <surname>Duan</surname>
    </contrib>
    <contrib contrib-type="author" corresp="no">
      <surname>Ding</surname>
    </contrib>
    <contrib contrib-type="author" corresp="no">
      <surname>Li</surname>
    </contrib>
    <contrib contrib-type="author" corresp="no">
      <surname>Miao</surname>
    </contrib>
    
    </doc>
    

    为了获得更好的结果,您必须在

    之后移动“和”文本部分
    position()=last()-1
    

    并且将 position()=last() 之后的文本留空,但这很容易推断和执行,不是吗?

    这看起来是一个准备不足的家庭作业!!

    【讨论】:

    • @michael.hor257k 我当然做到了! (使用haskell hxt xslt,还有saxon.jar):java -jar /usr/share/java/saxon.jar contrib.xml contrib2.xsl -- 结果:Duan, Ding, Li, Miao and
    • “和”必须放在“苗”之前,而不是逗号。
    • @michael.hor257k 我知道程序可以做得更好,但是如果没有根模板,position() 就无法工作
    猜你喜欢
    • 1970-01-01
    • 2019-09-02
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 2016-03-18
    • 1970-01-01
    相关资源
    最近更新 更多