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

以匹配元素结尾的同级分组

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

    我有一个非常大的XSL文件,可以将XML转换为CSV。基本上,XML的结构是表数据。这个表中大约有90列(不是我的决定!)。这些列组成列组。

    每个列组都有一个第一和第二个值、一个可选的第三个值和一个决定在组中选择哪个值的选择-这由F、S或T-(F)irst/(S)S econd/(T)hird表示。 行上的主键是日期时间列。

    XML如下(不是一个精简版本)。例如,我们可以说第30栏。

    <data>
     <columns>
      <column id="0">
       <name>Date Time</name>
       <type>DateTime</type>
      </column>
      <column id="1">
       <name>Column Group 1 First</name>
       <type>Double</type>
      </column>
      <column id="2">
       <name>Column Group 1 Second</name>
       <type>Double</type>
      </column>
      <column id="3">
       <name>Column Group 1 Third</name>
       <type>Double</type>
      </column>
      <column id="4">
       <name>Column Group 1 Selection</name>
       <type>String</type>
      </column>
      <column id="5">
       <name>Column Group 2 First</name>
       <type>Double</type>
      </column>
      <column id="6">
       <name>Column Group 2 Second</name>
       <type>Double</type>
      </column>
      <column id="7">
       <name>Column Group 2 Third</name>
       <type>Double</type>
      </column>
      <column id="8">
       <name>Column Group 2 Selection</name>
       <type>String</type>
      </column>
      <!-- This group does not have Third-->
      <column id="9">
       <name>Column Group 3 First</name>
       <type>Double</type>
      </column>
      <column id="10">
       <name>Column Group 3 Second</name>
       <type>Double</type>
      </column>
      <column id="11">
       <name>Column Group 3 Selection</name>
       <type>String</type>
      </column>
     </columns>
     <rows>
      <row id="0">
       <columns>
        <column id="0">
         <name>Date Time</name>
         <universalDate>2010-10-10 11:30:00</universalDate>
        </column>
        <!-- Group 1 - - - - - - - - - - - - - - - - -->
        <column id="1">
         <name>Column Group 1 First</name>
         <displayValue>100.123</displayValue>
         <value>100.123</value>
        </column>
        <column id="2">
         <name>Column Group 1 Second</name>
         <displayValue>Missing</displayValue>
         <value>-2.50E+08</value>
        </column>
        <column id="3">
         <name>Column Group 1 Third</name>
         <displayValue>Missing</displayValue>
         <value>-2.50E+08</value>
        </column>
        <column id="4">
         <name>Column Group 1 Selection</name>
         <displayValue>F</displayValue>
         <value>F</value>
        </column>
        <!-- Group 2 - - - - - - - - - - - - - - - - -->
        <column id="5">
         <name>Column Group 2 First</name>
         <displayValue>Missing</displayValue>
         <value>-2.50E+08</value>
        </column>
        <column id="6">
         <name>Column Group 2 Second</name>
         <displayValue>Missing</displayValue>
         <value>-2.50E+08</value>
        </column>
        <column id="7">
         <name>Column Group 2 Third</name>
         <displayValue>93.123</displayValue>
         <value>93.123</value>
        </column>
        <column id="8">
         <name>Column Group 2 Selection</name>
         <displayValue>T</displayValue>
         <value>T</value>
        </column>
        <!-- Group 3 - - - - - - - - - - - - - - - - -->
        <column id="9">
         <name>Column Group 3 First</name>
         <displayValue>500.3</displayValue>
         <value>500.3</value>
        </column>
        <column id="10">
         <name>Column Group 3 Second</name>
         <displayValue>22.21</displayValue>
         <value>22.21</value>
        </column>
        <column id="11">
         <name>Column Group 3 Third</name>
         <displayValue>S</displayValue>
         <value>S</value>
        </column>
       </columns>
      </row>
      <!-- Other rows omitted -->
     </rows>
    </data>
    

    期望的输出是:

    Date Time,Column Group 1 Primary,Column Group 1 Secondary,Column Group 1 Third,Column Group 1 Selection
    Date Time,Column Group 2 Primary,Column Group 2 Secondary,Column Group 2 Third,Column Group 2 Selection
    Date Time,Column Group 3 Primary,Column Group 3 Secondary,Column Group 3 Third,Column Group 3 Selection
    ... and so on ...
    

    所以实际的结果是:

    2010-10-10 11:30:00,100.123,,,F            
    2010-10-10 11:30:00,,,93.123,T             
    2010-10-10 11:30:00,500.3,22.21,,S         
    

    有几个规则: 如果displayValue=缺失,则输出空字符串。 如果组没有第三个值,则输出空字符串。

    我的XSL的第一个实例是对每一组看起来很可怕而且太大的列重复此检查。

    问题是-是否可以使用模板输出以下XML?我刚刚开始制作模板(感谢其他人在我的其他帖子中的帮助),但这让我有点卡住了。

    我可以在列和行之间进行链接,以输出表xml中的所有行列数据,但这或多或少是根据名称的第一部分将3列分组在一起。

    此实例的XSL如下所示:

    <xsl:for-each select="//rows/row">
    <xsl:value-of select="columns/column[name='Date Time']/universalDate"/>
    <xsl:text>,</xsl:text>
    <xsl:if test="number(columns/column[name='Column 1 First']/value)">
        <xsl:value-of select="format-number(columns/column[name='Column 1 First']/value,'0')"/>
      </xsl:if>
      <xsl:text>,</xsl:text>
      <xsl:if test="number(columns/column[name='Column 1 Second']/value)">
        <xsl:value-of select="format-number(columns/column[name='Column 1 Second']/value,'0')"/>
      </xsl:if>
      <xsl:text>,</xsl:text>
      <xsl:if test="number(columns/column[name='Column 1 Third']/value)">
        <xsl:value-of select="format-number(columns/column[name='Column 1 Third']/rawValue,'0')"/>
      </xsl:if>
      <xsl:text>,</xsl:text>
      <xsl:if test="columns/column[name='Column 1 Selection']/value='F'">
        <xsl:value-of select="format-number(columns/column[name='Column 1 First']/value,'0')"/>
      </xsl:if>
      <xsl:if test="columns/column[name='Column 1 Selection']/value='S'">
        <xsl:value-of select="format-number(columns/column[name='Column 1 Second']/value,'0')"/>
      </xsl:if>
      <xsl:if test="columns/column[name='Column 1 Selection']/value='T'">
        <xsl:value-of select="format-number(columns/column[name='Column 1 Third']/value,'0')"/>
      </xsl:if>
      <!-- new line required -->
      <xsl:text>&#xA;</xsl:text>
      <xsl:value-of select="columns/column[name='Date Time']/universalDate"/>
      <xsl:text>,</xsl:text>
      <xsl:if test="number(columns/column[name='Column 2 First']/value)">
        <xsl:value-of select="format-number(columns/column[name='Column 1 First']/value,'0')"/>
      </xsl:if>
      <xsl:text>,</xsl:text>
      <xsl:if test="number(columns/column[name='Column 2 Second']/value)">
        <xsl:value-of select="format-number(columns/column[name='Column 1 Second']/value,'0')"/>
      </xsl:if>
      <xsl:text>,</xsl:text>
      <xsl:if test="number(columns/column[name='Column 2 Third']/value)">
        <xsl:value-of select="format-number(columns/column[name='Column 2 Third']/value,'0')"/>
      </xsl:if>
      <xsl:text>,</xsl:text>
      <xsl:if test="columns/column[name='Column 2 Selection']/value='F'">
        <xsl:value-of select="format-number(columns/column[name='Column 2 First']/value,'0')"/>
      </xsl:if>
      <xsl:if test="columns/column[name='Column 2 Selection']/value='S'">
        <xsl:value-of select="format-number(columns/column[name='Column 2 Second']/value,'0')"/>
      </xsl:if>
      <xsl:if test="columns/column[name='Column 2 Selection']/value='T'">
        <xsl:value-of select="format-number(columns/column[name='Column 2 Third']/value,'0')"/>
      </xsl:if>
      <!-- new line required -->
      <xsl:text>&#xA;</xsl:text>
    
      <!-- and so on.......  -->
    

    很抱歉在第一次澄清的时候。

    谢谢,

    安德仕

    1 回复  |  直到 14 年前
        1
  •  1
  •   user357812user357812    14 年前

    此样式表:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text"/>
        <xsl:template match="row/columns/column[substring(name,16)='First']">
            <xsl:variable name="vOptional"
                          select="following::column[2]
                                     [substring(name,16)='Third']"/>
            <xsl:value-of select="concat(../column[1]/universalDate,',',
                                         displayValue[.!='Missing'],',',
                                         following::column[1]
                                            /displayValue[.!='Missing'],',',
                                         $vOptional/displayValue[.!='Missing'],',',
                                         following::column[2 + boolean($vOptional)]
                                            /displayValue[.!='Missing'],'&#xA;')"/>
        </xsl:template>
        <xsl:template match="data/columns|column"/>
    </xsl:stylesheet>
    

    输出:

    2010-10-10 11:30:00,100.123,,,F
    2010-10-10 11:30:00,,,93.123,T
    2010-10-10 11:30:00,500.3,22.21,,S
    

    编辑: 更好。对不起,我以前的逻辑是固定的。