从XML按特定表顺序进行XLS转换

时间:2019-06-05 02:09:38

标签: xml xslt tabulate

我下面有一个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 个答案:

答案 0 :(得分:1)

这一点都不小,尤其是。在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

答案 1 :(得分:1)

另一个选择是生成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