【问题标题】:XSL Getting the last node of a selectionXSL 获取选择的最后一个节点
【发布时间】:2011-03-04 00:43:43
【问题描述】:

我有以下包含图像数据的 xml 文件:

<images>
<aid>1</aid>
  <imid>1</imid>
    <src>img1.jpg</src>
</images>
<images>
<aid>1</aid>
  <imid>2</imid>
    <src>img2.jpg</src>
</images>
<images>
<aid>1</aid>
  <imid>3</imid>
    <src>img3.jpg</src>
</images>
<images>
<aid>2</aid>
  <imid>1</imid>
    <src>img1.jpg</src>
</images>
<images>
<aid>2</aid>
  <imid>2</imid>
    <src>img2.jpg</src>
</images>
<images>
etc...

我想从每个 aid 只获得最后一个 imid 并将其作为结果呈现,在本例中为:
aid=1 和 imid=3 和 src=img3.jpg
aid=2 and imid=2 and src=img2.jpg

(在原始文件中,一个aid可以包含很多imid 's)

下面的 xsl 选择只会给我所有图像的完整选择中的最后一张图像。

<xsl:for-each select="(/images[aid&gt;=1 and imid])[last()]">

以下 xsl 选择为我提供了 aid 中每个第一个 imid 的结果。

<xsl:for-each select="(/images[aid&gt;=1 and imid=1])">

我如何调整该代码,使其只给我每个aid的最后一个imid

【问题讨论】:

  • 您说您想要每个 aid 中的最后一个 imid,但这不是您的源 XML 的形成方式。您可能想再看看您的输入或修正您的示例。
  • 好问题,+1。请参阅我的答案以获得完整、简短且简单的 XSLT 1.0 解决方案。 :)

标签: xml xslt


【解决方案1】:

在 XSLT 1.0 中:

<xsl:key name="kImagesByAid" match="images" use="aid">
<xsl:variable name="vLastImids" 
     select="/*/images[count(.|key('kImageByAid',aid)[last()])=1]/imid"/>

【讨论】:

    【解决方案2】:

    此 XSLT 1.0 转换:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:key name="kImgByAid" match="images" use="aid"/>
    
     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match=
      "images[not(generate-id()
                 =generate-id(key('kImgByAid',aid)[last()])
                 )
              ]"/>
    </xsl:stylesheet>
    

    应用于提供的 XML 文档时(包装在顶部元素中以形成良好的格式):

    <gallery>
        <images>
            <aid>1</aid>
            <imid>1</imid>
            <src>img1.jpg</src>
        </images>
        <images>
            <aid>1</aid>
            <imid>2</imid>
            <src>img2.jpg</src>
        </images>
        <images>
            <aid>1</aid>
            <imid>3</imid>
            <src>img3.jpg</src>
        </images>
        <images>
            <aid>2</aid>
            <imid>1</imid>
            <src>img1.jpg</src>
        </images>
        <images>
            <aid>2</aid>
            <imid>2</imid>
            <src>img2.jpg</src>
        </images>
    </gallery>
    

    产生想要的正确结果:

    <gallery>
      <images>
        <aid>1</aid>
        <imid>3</imid>
        <src>img3.jpg</src>
      </images>
      <images>
        <aid>2</aid>
        <imid>2</imid>
        <src>img2.jpg</src>
      </images>
    </gallery>
    

    解释

    1. 身份规则(模板)“按原样”复制每个节点。

    2. 有一个单一的覆盖模板,它排除了任何不是其组中最后一个的 images 元素。

    3. 使用经典的 Muenchian 方法实现分组。

    【讨论】:

      【解决方案3】:

      假设您使用的是 XSLT 2.0,

      <xsl:for-each-group select="//images" group-by="aid">
        <xsl:variable name="last" select="current-group()[last()]"/>
        <out aid="{$last/aid}" imid="{$last/imid}" src="{$last/src}"/>
      </xsl:for-each-group>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-14
        相关资源
        最近更新 更多