Преобразование XLS из XML в определенном порядке таблицы - PullRequest
0 голосов
/ 05 июня 2019

Ниже у меня есть XML-файл, для которого я пытаюсь создать шаблон XSLT для табулирования некоторых узлов. Пусть кто-нибудь может мне помочь, пожалуйста.

<Main>
    <Document>Doc.1</Document>
    <Cini>DDFR</Cini>
    <List>
        <SubList>
            <CdTa>ABC</CdTa>
            <NN>XYZ</NN>
            <ND>
                <RiS>
                    <RiN>
                        <NSE14>
                            <MNRs>
                                <MRD>
                                    <NR>
                                        <N1>393</N1>
                                        <N2>720</N2>
                                        <SNR>
                                            <NR_i>203</NR_i>
                                            <NR_f>49994</NR_f>
                                        </SNR>
                                    </NR>
                                </MRD>
                                <MRD>
                                    <NR>
                                        <N1>687</N1>
                                        <N2>345</N2>
                                        <SNR>
                                            <NR_i>55005</NR_i>
                                            <NR_f>1229996</NR_f>
                                        </SNR>
                                    </NR>
                                </MRD>
                            </MNRs>
                            <GNRs>
                                <RD>
                                    <NR>
                                        <N1>649</N1>
                                        <N2>111</N2>
                                        <SNR>
                                            <NR_i>55400</NR_i>
                                            <NR_f>877</NR_f>
                                        </SNR>
                                    </NR>
                                </RD>
                            </GNRs>
                            <MSNRs>
                                <NR>
                                    <N1>748</N1>
                                    <N2>5624</N2>
                                    <SNR>
                                        <NR_i>8746</NR_i>
                                        <NR_f>7773</NR_f>
                                    </SNR>
                                </NR>
                                <NR>
                                    <N1>124</N1>
                                    <N2>54</N2>
                                    <SNR>
                                        <NR_i>8847</NR_i>
                                        <NR_f>5526</NR_f>
                                    </SNR>
                                </NR>
                            </MSNRs>
                        </NSE14>
                        <NSE12>
                            <MBB>990</MBB>
                            <MRB>123</MRB>
                        </NSE12>
                        <MGE13>
                            <TBB>849</TBB>
                            <TRB>113</TRB>
                        </MGE13>
                    </RiN>
                </RiS>
            </ND>
        </SubList>
    </List>
</Main>

И этот XSLT-код

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html> 
<body>
  <table border="1">
<tr bgcolor="#FFF833">
      <th style="text-align:left">MNRs</th>
      <th style="text-align:left">GNRs</th>
      <th style="text-align:left">MSNRs</th>
</tr>
    <tr bgcolor="#9acd32">
      <th style="text-align:left">N1</th>
      <th style="text-align:left">N2</th>
      <th style="text-align:left">NR_i</th>
      <th style="text-align:left">NR_f</th>
      <th style="text-align:left">N1</th>
      <th style="text-align:left">N2</th>
      <th style="text-align:left">NR_i</th>
      <th style="text-align:left">NR_f</th>
      <th style="text-align:left">N1</th>
      <th style="text-align:left">N2</th>
      <th style="text-align:left">NR_i</th>
      <th style="text-align:left">NR_f</th>
    </tr>

    <xsl:for-each select="//MNRs//NR">
    <tr>
      <td><xsl:value-of select="N1"/></td>
      <td><xsl:value-of select="N2"/></td>
      <xsl:for-each select="SNR">
          <td><xsl:value-of select="NR_i"/></td>
          <td><xsl:value-of select="NR_f"/></td>
      </xsl:for-each>
    </xsl:for-each>

    <xsl:for-each select="//GNRs//NR">
      <td><xsl:value-of select="N1"/></td>
      <td><xsl:value-of select="N2"/></td>
      <xsl:for-each select="SNR">
          <td><xsl:value-of select="NR_i"/></td>
          <td><xsl:value-of select="NR_f"/></td>
      </xsl:for-each>
    </xsl:for-each>

    <xsl:for-each select="//MSNRs//NR">
      <td><xsl:value-of select="N1"/></td>
      <td><xsl:value-of select="N2"/></td>
      <xsl:for-each select="SNR">
          <td><xsl:value-of select="NR_i"/></td>
          <td><xsl:value-of select="NR_f"/></td>
      </xsl:for-each>
    </tr>
    </xsl:for-each>
  </table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

С текущим XSLT-кодом я получаю вывод, который не является той структурой, которую я хотел бы получить, поскольку получаю только некоторые значения. Дело в том, что есть 3 родительских узла с одинаковыми именами детей. Родительскими узлами являются MNR, GNR и MSNR

+------+------+-------+---------+----+----+------+------+----+----+------+------+
| MNRs | GNRs | MSNRs |         |    |    |      |      |    |    |      |      |
+------+------+-------+---------+----+----+------+------+----+----+------+------+
| N1   | N2   | NR_i  | NR_f    | N1 | N2 | NR_i | NR_f | N1 | N2 | NR_i | NR_f |
+------+------+-------+---------+----+----+------+------+----+----+------+------+
| 393  | 720  | 203   | 49994   |    |    |      |      |    |    |      |      |
+------+------+-------+---------+----+----+------+------+----+----+------+------+
| 687  | 345  | 55005 | 1229996 |    |    |      |      |    |    |      |      |
+------+------+-------+---------+----+----+------+------+----+----+------+------+

И я хотел бы получить этот вывод:

+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
|             MNRs              |          GNRs            |           MSNRs          |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
| N1   | N2   | NR_i  | NR_f    | N1  | N2  | NR_i  | NR_f | N1  | N2   | NR_i | NR_f |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
| 393  | 720  | 203   | 49994   | 649 | 111 | 55400 | 877  | 748 | 5624 | 8746 | 7773 |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+
| 687  | 345  | 55005 | 1229996 |     |     |       |      | 124 | 54   | 8847 | 5526 |
+------+------+-------+---------+-----+-----+-------+------+-----+------+------+------+ 

Спасибо за любую помощь.

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Другой вариант - сгенерировать 3 отдельные таблицы и отображать их рядом.Это намного проще - но результат визуально отличается, и различия зависят от используемого браузера (я предполагаю, что это можно решить с помощью большего количества CSS):

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <html> 
        <body>
            <xsl:for-each select="//MNRs | //GNRs | //MSNRs">
                <table  border="1" width="25%" style="display:inline-block">
                    <!-- header -->
                    <tr>
                        <th colspan="4">
                            <xsl:value-of select="name()"/>
                        </th>
                    </tr>
                    <tr>
                        <th>N1</th>
                        <th>N2</th>
                        <th>NR_i</th>
                        <th>NR_f</th>
                    </tr>
                    <!-- data -->
                    <xsl:for-each select=".//NR">
                        <tr>
                            <td>
                                <xsl:value-of select="N1"/>
                            </td>
                            <td>
                                <xsl:value-of select="N2"/>
                            </td>
                            <td>
                                <xsl:value-of select="SNR/NR_i"/>
                            </td>
                            <td>
                                <xsl:value-of select="SNR/NR_f"/>
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </xsl:for-each>
        </body>
    </html>     
</xsl:template>

Результат

<html>
<body>
<table border="1" width="25%" style="display:inline-block">
<tr><th colspan="4">MNRs</th></tr>
<tr>
<th>N1</th>
<th>N2</th>
<th>NR_i</th>
<th>NR_f</th>
</tr>
<tr>
<td>393</td>
<td>720</td>
<td>203</td>
<td>49994</td>
</tr>
<tr>
<td>687</td>
<td>345</td>
<td>55005</td>
<td>1229996</td>
</tr>
</table>
<table border="1" width="25%" style="display:inline-block">
<tr><th colspan="4">GNRs</th></tr>
<tr>
<th>N1</th>
<th>N2</th>
<th>NR_i</th>
<th>NR_f</th>
</tr>
<tr>
<td>649</td>
<td>111</td>
<td>55400</td>
<td>877</td>
</tr>
</table>
<table border="1" width="25%" style="display:inline-block">
<tr><th colspan="4">MSNRs</th></tr>
<tr>
<th>N1</th>
<th>N2</th>
<th>NR_i</th>
<th>NR_f</th>
</tr>
<tr>
<td>748</td>
<td>5624</td>
<td>8746</td>
<td>7773</td>
</tr>
<tr>
<td>124</td>
<td>54</td>
<td>8847</td>
<td>5526</td>
</tr>
</table>
</body>
</html>

Предоставлено в Safari:

enter image description here

Отображается в Firefox:

enter image description here

1 голос
/ 05 июня 2019

Это совсем не тривиально, особеннов XSLT 1.0.Я бы посоветовал вам попробовать это так:

XSL 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
    <html> 
        <body>
            <table border="1" width="80%">
                <!-- header -->
                <tr>
                    <th colspan="4">MNRs</th>
                    <th colspan="4">GNRs</th>
                    <th colspan="4">MSNRs</th>
                </tr>
                <tr>
                    <!-- MNRs -->
                    <th>N1</th>
                    <th>N2</th>
                    <th>NR_i</th>
                    <th>NR_f</th>
                    <!-- GNRs -->
                    <th>N1</th>
                    <th>N2</th>
                    <th>NR_i</th>
                    <th>NR_f</th>
                    <!-- MSNRs -->
                    <th>N1</th>
                    <th>N2</th>
                    <th>NR_i</th>
                    <th>NR_f</th>
                </tr>
                <!-- data -->
                <xsl:call-template name="rows">
                    <xsl:with-param name="MNRs" select="//MNRs//NR"/>
                    <xsl:with-param name="GNRs" select="//GNRs//NR"/>
                    <xsl:with-param name="MSNRs" select="//MSNRs//NR"/>
                </xsl:call-template>
            </table>
        </body>
    </html>     
</xsl:template>

<xsl:template name="rows">
    <xsl:param name="MNRs"/>
    <xsl:param name="GNRs"/>
    <xsl:param name="MSNRs"/>
    <xsl:param name="i" select="1"/>
    <xsl:if test="$MNRs[$i] or $GNRs[$i] or $MSNRs[$i]">
        <tr>
            <!-- MNRs -->
            <td>
                <xsl:value-of select="$MNRs[$i]/N1"/>
            </td>
            <td>
                <xsl:value-of select="$MNRs[$i]/N2"/>
            </td>
            <td>
                <xsl:value-of select="$MNRs[$i]/SNR/NR_i"/>
            </td>
            <td>
                <xsl:value-of select="$MNRs[$i]/SNR/NR_f"/>
            </td>
            <!-- GNRs -->
            <td>
                <xsl:value-of select="$GNRs[$i]/N1"/>
            </td>
            <td>
                <xsl:value-of select="$GNRs[$i]/N2"/>
            </td>
            <td>
                <xsl:value-of select="$GNRs[$i]/SNR/NR_i"/>
            </td>
            <td>
                <xsl:value-of select="$GNRs[$i]/SNR/NR_f"/>
            </td>
            <!-- MSNRs -->
            <td>
                <xsl:value-of select="$MSNRs[$i]/N1"/>
            </td>
            <td>
                <xsl:value-of select="$MSNRs[$i]/N2"/>
            </td>
            <td>
                <xsl:value-of select="$MSNRs[$i]/SNR/NR_i"/>
            </td>
            <td>
                <xsl:value-of select="$MSNRs[$i]/SNR/NR_f"/>
            </td>
        </tr>
        <!-- recursive call -->
        <xsl:call-template name="rows">     
            <xsl:with-param name="MNRs" select="$MNRs"/>
            <xsl:with-param name="GNRs" select="$GNRs"/>
            <xsl:with-param name="MSNRs" select="$MSNRs"/>
            <xsl:with-param name="i" select="$i + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

Применительно к вашему примеру ввода, результат будет:

Результат

<html>
<body>
<table border="1" width="80%">
<tr>
<th colspan="4">MNRs</th>
<th colspan="4">GNRs</th>
<th colspan="4">MSNRs</th>
</tr>
<tr>
<th>N1</th>
<th>N2</th>
<th>NR_i</th>
<th>NR_f</th>
<th>N1</th>
<th>N2</th>
<th>NR_i</th>
<th>NR_f</th>
<th>N1</th>
<th>N2</th>
<th>NR_i</th>
<th>NR_f</th>
</tr>
<tr>
<td>393</td>
<td>720</td>
<td>203</td>
<td>49994</td>
<td>649</td>
<td>111</td>
<td>55400</td>
<td>877</td>
<td>748</td>
<td>5624</td>
<td>8746</td>
<td>7773</td>
</tr>
<tr>
<td>687</td>
<td>345</td>
<td>55005</td>
<td>1229996</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>124</td>
<td>54</td>
<td>8847</td>
<td>5526</td>
</tr>
</table>
</body>
</html>

отображается как:

enter image description here

...