Группирование братьев и сестер, заканчивающихся соответствующим элементом - PullRequest
0 голосов
/ 11 ноября 2010

У меня очень большой XSL-файл для преобразования XML в CSV.По сути, структура XML - это табличные данные.В этой таблице около 90 столбцов (не мое решение!).Эти столбцы составляют группу столбцов.

Каждая группа столбцов имеет первое и второе значения, необязательное третье значение и выбор, который определяет, какое значение было выбрано в группе - это обозначается буквами F, S илиT - (F) первая / (S) секунда / (T) хирд.Основным ключом в строке является столбец «Дата-время».

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 Ответ

1 голос
/ 11 ноября 2010

Эта таблица стилей:

<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

Редактировать: Лучше. Я был заперт в предыдущей логике, извините.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...