0

我正在尝试使用 XSLT 将 XML(由源生成)转换为 CSV。

下面是由外部源生成的输入 XML。我不确定这是否是一个有效的 xml,因为 Details 标记的值是一个大列表。

<Data>
<Details COLUMNS="Counterparty,Iteration,StartDateTime,Quantity">
ABC,1,23/10/2013 06:00,10
ABC,1,23/10/2013 06:30,12
ABC,1,23/10/2013 07:00,15
ABC,1,23/10/2013 07:30,5
ABC,1,23/10/2013 08:00,180
ABC,1,23/10/2013 08:30,87
ABC,1,23/10/2013 09:00,88
ABC,1,23/10/2013 09:30,56
ABC,1,23/10/2013 10:00,13
ABC,1,24/10/2013 00:00,0
ABC,1,24/10/2013 00:30,8.7
ABC,1,24/10/2013 01:00,100.9
ABC,1,24/10/2013 01:30,1.1
ABC,1,24/10/2013 02:00,2.2
ABC,1,24/10/2013 02:30,3.2
ABC,1,24/10/2013 03:00,20
ABC,1,24/10/2013 03:30,30
</Details>
</Data>

我想创建一个可以将此 XML 转换为 CSV 的 XSLT,如下所示。我查看了许多在线链接,但无法创建这样的 XSL 转换。请帮忙!

Counterparty,StartDate,StartTime,EndTime,Volume
ABC,23/10/2013,0600,0630,10
ABC,23/10/2013,0630,0700,12
ABC,23/10/2013,0700,0730,15
ABC,23/10/2013,0730,0800,5
ABC,23/10/2013,0800,0830,180
.
.
.
.
ABC,24/10/2013,0300,0330,20
ABC,24/10/2013,0330,0400,30

根据注释添加更多信息:我需要进入元素文本并对其进行操作(添加/编辑/删除文本)。如果 XSLT 2.0 能够轻松地操作文本,我愿意使用它。每行文本之间有一个 LF 和 CR。请让我知道最好的方法。谢谢!

问候, 阿米特

4

1 回答 1

1

以下 XSLT 2.0 产生所需的输出

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes" />

  <xsl:template match="/Data">
    <xsl:text>Counterparty,StartDate,StartTime,EndTime,Volume&#10;</xsl:text>

    <xsl:for-each select="tokenize(Details/text(), '[&#10;&#13;]')">

      <xsl:analyze-string select="." regex="\s*([^,]+,[^,]+,[^,]+) +([0-9]+):([0-9]+),([0-9\.]+)">

        <xsl:matching-substring>
          <xsl:variable name="prefix" select="regex-group(1)"/>
          <xsl:variable name="hours" select="regex-group(2)"/>
          <xsl:variable name="minutes" select="regex-group(3)"/>
          <xsl:variable name="suffix" select="regex-group(4)"/>

          <xsl:variable name="startTime" select="number($hours) * 60 + number($minutes)"/>
          <xsl:variable name="endTime" select="$startTime + 30"/>
          <xsl:variable name="endHours" select="format-number($endTime div 60, '00')"/>
          <xsl:variable name="endMinutes" select="format-number($endTime mod 60, '00')"/>

          <xsl:value-of select="concat($prefix, ',', $hours, $minutes, ',', $endHours, $endMinutes, ',', $suffix)"/><xsl:text>&#10;</xsl:text>          
        </xsl:matching-substring>

      </xsl:analyze-string>
    </xsl:for-each>

  </xsl:template>

</xsl:stylesheet>

笔记:

  • XSLT 对输入文件的列内容及其分隔符做了一些假设。如果问题中提供的示例不能很好地代表生产数据,regex则可能必须更改表达式。
  • 转换应该适用于所有具有换行符换行符和/或换行符或其任何组合的输入文件。不过,我还没有尝试过。
  • XSLT 对如何得出结束时间(+ 30 分钟)做出了一些假设。这可能必须改变。
于 2013-11-09T17:32:29.307 回答