xslt从节点属性创建以逗号分隔的列表

时间:2013-08-13 08:53:19

标签: xslt

我有以下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

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

3 个答案:

答案 0 :(得分:2)

如果你可以切换到XSLT 2,它就变得微不足道了。

替换

<xsl:value-of select="Product/@skn"/>

<xsl:value-of select="Product/@skn" separator=","/>

答案 1 :(得分:2)

我只想为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

答案 2 :(得分:1)

您可以使用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>