代码之家  ›  专栏  ›  技术社区  ›  Andez

XSL转换XML

  •  1
  • Andez  · 技术社区  · 14 年前

    我有以下格式的xml:

    <fileExport>
      <rows>
        <row id="0">
          <columns>
            <column id="0">
              <name>Date Time</name>
              <value>2010-10-2 23:00:00 GMT</value>
            </column>
            <column id="1">
              <name>Primary</name>
              <value>100.1</value> 
            </column>
            <column id="2">
              <name>Manual</name>
              <value>20.5</value>
            </column>
            ...
          </columns>
        </row>
        <row id="1">
          <columns>
            <column id="0">
              <name>Date Time</name>
              <value>2010-10-3 00:00:00 GMT</value>
            </column>
            <column id="1">
              <name>Primary</name>
              <value>110.5</value> 
            </column>
            ...
            <column id="2">
              <name>Manual</name>
              <value>23.1</value>
            </column>
          </columns>
        </row>
      </rows>  
    </fileExport>
    

    现在的想法是将其转换为CSV文本。一切看起来都很好,但是上面每行有32列。要将此转换为CSV,我使用以下XSL:

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:output method="text" />
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="/">
        <xsl:for-each select="//rows/row">
          <!-- Now add a new row for each column -->
    
          <!-- first row in file for this row in table -->
          <xsl:text>A</xsl:text>
          <xsl:text>,</xsl:text>
          <xsl:value-of select="columns/column[name='Date Time']/value"/>
          <xsl:text>,</xsl:text>
          <xsl:value-of select="columns/column[name='Primary']/value"/>
          <xsl:text>,</xsl:text>
          <xsl:text>P</xsl:text>
          <xsl:text>&#xA;</xsl:text>
    
          <!-- second row in file for this row in table -->
          <xsl:text>A</xsl:text>
          <xsl:text>,</xsl:text>
          <xsl:value-of select="columns/column[name='Date Time']/value"/>  
          <xsl:text>,</xsl:text>
          <xsl:value-of select="columns/column[name='Manual']/value"/>
          <xsl:text>,</xsl:text>
          <xsl:text>M</xsl:text>
          <xsl:text>&#xA;</xsl:text>
    
          ... now repeat for the next 30 columns ...
    
          <!-- next row in table-->
        </xsl:for-each>
      <xsl:text>&lt;EOF&gt;</xsl:text>
      </xsl:template>
    </xsl:stylesheet>
    

    现在我们得到的结果是:

    A,2010-10-2 23:00:00 GMT,100.1,P
    A,2010-10-2 23:00:00 GMT,20.5,M
    A,2010-10-3 00:00:00 GMT,110.5,P
    A,2010-10-3 00:00:00 GMT,23.1,M
    <EOF>
    

    问题是,在XML中有32列左右,是否可以缩短实现相同结果所需的XSL?

    谢谢,

    安德仕

    2 回复  |  直到 14 年前
        1
  •  1
  •   dvhh    14 年前

    这能帮上忙吗?

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="text" />
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="/fileExport">
         <xsl:for-each select="rows/row">
             <xsl:variable name="date" select="columns/column[name='Date Time']/value"/>
             <xsl:for-each select="columns/column">
                 <xsl:if test="name!='Date Time'">
                    <xsl:text>A</xsl:text>
                    <xsl:text>,</xsl:text>
                    <xsl:value-of select="$date"/>
                    <xsl:text>,</xsl:text>
                    <xsl:value-of select="value"/>
                    <xsl:text>,</xsl:text>
                     <xsl:choose>
                         <xsl:when test="name='Primary'">P</xsl:when>
                         <xsl:when test="name='Manual'">M</xsl:when>
                         ....
                    </xsl:choose>
                    <xsl:text>&#xA;</xsl:text>
                    </xsl:if>
             </xsl:for-each>
         </xsl:for-each>
        <xsl:text>&lt;EOF&gt;</xsl:text>
        </xsl:template>
    </xsl:stylesheet>
    
        2
  •  4
  •   user357812 user357812    14 年前

    此样式表:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text" />
        <xsl:strip-space elements="*"/>
        <xsl:template match="row">
            <xsl:text>A</xsl:text>
            <xsl:apply-templates/>
            <xsl:text>&#xA;</xsl:text>
        </xsl:template>
        <xsl:template match="value">
            <xsl:value-of select="concat(',',.)"/>
        </xsl:template>
        <xsl:template match="column[name='Primary' or name='Manual']">
            <xsl:apply-templates/>
            <xsl:value-of select="concat(',',substring(name,1,1))"/>
        </xsl:template>
        <xsl:template match="row[position() mod 2]/*/column[name='Manual']|
                             row[position() mod 2 = 0]/*/column[name='Primary']|
                             text()" priority="1"/>
    </xsl:stylesheet>
    

    输出:

    A,2010-10-2 23:00:00 GMT,100.1,P
    A,2010-10-3 00:00:00 GMT,23.1,M