【问题标题】:xslt to create comma-separated list from node attributesxslt 从节点属性创建逗号分隔的列表
【发布时间】:2013-08-14 03:02:12
【问题描述】:

我有以下 XML:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Export channel="XXX" date_stamp="20130113 01:01:01">
  <Script show_code="ALR" script_no="13081300" duration="1">
    <Product skn="222363" />
    <Product skn="203092" />
    <Product skn="219585" />
    <Product skn="201371" />
    <Product skn="201029" />
    <Product skn="202648" />
    <Product skn="201294" />
    <Product skn="201370" />
  </Script>
  <Script show_code="BQV" script_no="13081301" duration="1">
    <Product skn="400063" />
    <Product skn="203089" />
    <Product skn="212059" />
    <Product skn="202770" />
    <Product skn="400292" />
    <Product skn="400108" />
    <Product skn="400407" />
  </Script>
</Export>

我想将 Product @skn 值输出(以简单的文本格式)作为逗号分隔的实体。我目前的 XSLT 是..

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="utf-8" indent="no" media-type="text/xml" />

<xsl:template match="/">

    <xsl:for-each select="/EPGExport/Script">

    <xsl:value-of select="substring(@script_no,5,2)"/>/<xsl:value-of select="substring(@script_no,3,2)"/>/20<xsl:value-of select="substring(@script_no,1,2)"/><xsl:text>&#9;</xsl:text>
    <xsl:value-of select="substring(@script_no,7,2)"/>:00<xsl:text>&#9;</xsl:text>
    <xsl:value-of select="@show_code"/><xsl:text>&#9;</xsl:text>
    <xsl:value-of select="Product/@skn"/><xsl:text>&#10;</xsl:text>

    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

输出如下:

13/08/2013  00:00   ALR 222363

13/08/2013  01:00   BQV 400063

但我希望最后一个制表符分隔值输出为:

13/08/2013  00:00   ALR 222363,203092,219585,201371,201029,202648,201294,201370

13/08/2013  01:00   BQV 400063,203089,212059,202770,400292,400108,400407

非常感谢任何帮助。谢谢。

【问题讨论】:

    标签: xslt


    【解决方案1】:

    我只想为Product 元素添加一个模板。在该模板中,您可以输出每个@skn 并使用position() 来确定是否需要添加逗号或换行符。以下是我所指的。

    您可以将此模板添加到您现有的 XSL:

    <xsl:template match="Product">
      <xsl:value-of select="@skn"/>
      <xsl:choose>
        <xsl:when test="position()=last()">
          <xsl:text>&#10;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>,</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>
    

    然后你会换行:

    <xsl:value-of select="Product/@skn"/><xsl:text>&#10;</xsl:text>
    

    到这里:

    <xsl:apply-templates select="Product"/>
    

    它会在运行时产生这个输出:

    13/08/2013  00:00   ALR 222363,203092,219585,201371,201029,202648,201294,201370
    13/08/2013  01:00   BQV 400063,203089,212059,202770,400292,400108,400407
    

    【讨论】:

    • 实际上我昨天最终自己解决了这个问题,使用嵌套的 for-each 方法与 ShaharB 建议的方式相同(虽然我当时无法更新这个问题) - 但是我更喜欢这个模板解决方案,感觉有点整洁。谢谢。
    【解决方案2】:

    如果您可以切换到 XSLT 2,这将变得微不足道。

    替换

    &lt;xsl:value-of select="Product/@skn"/&gt;

    &lt;xsl:value-of select="Product/@skn" separator=","/&gt;

    【讨论】:

      【解决方案3】:

      你可以使用 Matthew 的答案,但是不用写一个新的模板,只写一个嵌套的 for-each

      所以不是

      <xsl:value-of select="Product/@skn"/><xsl:text>&#10;</xsl:text>
      

      使用

      <xsl:for-each select="Product">
         <xsl:value-of select="@skn"/>
         <xsl:choose>
            <xsl:when test="position()=last()">
              <xsl:text>&#10;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>,</xsl:text>
            </xsl:otherwise>
         </xsl:choose>
      </xsl:for-each>
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-04
      • 2016-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多