更高效的XSLT,用于将XML文档转换为CSV平面文件

时间:2012-03-12 23:44:15

标签: xml xslt

我有一个可以工作的XSLT,并将我的XML文档翻译成CSV。但它很难读(我不喜欢所有的“../../”引用)而且我想知道这些是否也会影响性能 - 我正在改造的文件很大。我看了几个不同的例子,但我只能使下面的一个例子工作。

所以我的问题是: 1.可以将此XSLT重写为更简洁,并且不使用“../ ..”引用。 2.“../ ..”类型引用的效率低于以某种方式存储值。

以下示例。 谢谢, 约翰


继承XSLT:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
   <xsl:apply-templates select="Document"/>
</xsl:template>
<xsl:template match="Document">
   <xsl:apply-templates select="DocBody"/>
</xsl:template>
<xsl:template match="DocBody">
   <xsl:apply-templates select="Values"/>
</xsl:template>
<xsl:template match="Values">
   <xsl:apply-templates select="IntervalValues"/>
</xsl:template>
<xsl:template match="IntervalValues">
   <xsl:apply-templates select="Quantity"/>
</xsl:template>
<xsl:template match="Quantity">
   <xsl:value-of select="concat(../../../../DocHeader/DocTitle,',',../../../../DocHeader/CreatedAt,',',../../../DeliveryDate,',',../../../DeliveryHour,',',../Interval,',',Type,',',Value)"/>
   <xsl:text>&#xA;</xsl:text>
</xsl:template>
</xsl:stylesheet>

下面是一个小的XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<Document>
<DocHeader>
<DocTitle>Totals Report</DocTitle>
<DocRevision>1</DocRevision>
<CreatedAt>2011-02-10T21:25:00</CreatedAt>
</DocHeader>
<DocBody>
<DeliveryDate>2011-02-10</DeliveryDate>
<DeliveryHour>22</DeliveryHour>
<Values>
<IntervalValues>
<Interval>1</Interval>
<Quantity>
<Type>Energy</Type>
<Value>18053.5</Value>
</Quantity>
<Quantity>
<Type>Loss</Type>
<Value>438.7</Value>
</Quantity>
<Quantity>
<Type>Load</Type>
<Value>17614.8</Value>
</Quantity>
</IntervalValues>
<IntervalValues>
<Interval>2</Interval>
<Quantity>
<Type>Energy</Type>
<Value>17940.7</Value>
</Quantity>
<Quantity>
<Type>Loss</Type>
<Value>437.7</Value>
</Quantity>
<Quantity>
<Type>Load</Type>
<Value>17503</Value>
</Quantity>
</IntervalValues>
<IntervalValues>
<Interval>3</Interval>
<Quantity>
<Type>Energy</Type>
<Value>17871.7</Value>
</Quantity>
<Quantity>
<Type>Loss</Type>
<Value>437.4</Value>
</Quantity>
<Quantity>
<Type>Load</Type>
<Value>17434.3</Value>
</Quantity>
</IntervalValues>
</Values>
</DocBody>
</Document>

下载示例输出

Totals Report,2011-02-10T21:25:00,2011-02-10,22,1,Energy,18053.5
Totals Report,2011-02-10T21:25:00,2011-02-10,22,1,Loss,438.7
Totals Report,2011-02-10T21:25:00,2011-02-10,22,1,Load,17614.8
Totals Report,2011-02-10T21:25:00,2011-02-10,22,2,Energy,17940.7
Totals Report,2011-02-10T21:25:00,2011-02-10,22,2,Loss,437.7
Totals Report,2011-02-10T21:25:00,2011-02-10,22,2,Load,17503
Totals Report,2011-02-10T21:25:00,2011-02-10,22,3,Energy,17871.7
Totals Report,2011-02-10T21:25:00,2011-02-10,22,3,Loss,437.4
Totals Report,2011-02-10T21:25:00,2011-02-10,22,3,Load,17434.3

2 个答案:

答案 0 :(得分:1)

您可以稍早提取公共部分,如下所示:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:variable name="head">
 <xsl:for-each select="Document/DocHeader">
  <xsl:value-of  select="concat(DocTitle,',',CreatedAt,',')"/>
 </xsl:for-each>
 <xsl:for-each select="Document/DocBody">
  <xsl:value-of  select="concat(DeliveryDate,',',DeliveryHour,',')"/>
 </xsl:for-each>
</xsl:variable>

<xsl:template match="/">
 <xsl:apply-templates select="Document/DocBody/Values/IntervalValues/Quantity"/>
</xsl:template>

<xsl:template match="Quantity">
 <xsl:value-of select="concat($head,../Interval,',',Type,',',Value)"/>
 <xsl:text>&#xA;</xsl:text>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

这对你来说更容易阅读吗?

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:template match="/Document">
    <xsl:variable name="header" select="DocHeader"/>
    <xsl:variable name="body" select="DocBody" />
    <xsl:for-each select="DocBody/Values">
      <xsl:for-each select="IntervalValues">
        <xsl:variable name="interval" select="Interval"/>
        <xsl:for-each select="Quantity">
        <xsl:value-of select="$header/DocTitle"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$header/CreatedAt"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$body/DeliveryDate"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$body/DeliveryHour"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="$interval"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Type"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Value"/>
        <xsl:text>&#xA;</xsl:text>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>