如何使用xslt生成包含一组数据的多个表?

时间:2013-05-31 13:09:39

标签: xslt

我有以下XML

    <ArrayOfOperatorStation>
     <OperatorStation>
        <Name>OS1</Name>
        <OS>Microsoft Windows XP Professional</OS>
        <IP>172.20.254.90</IP>
        <Version>5.1.2600</Version>
        <Alive>true</Alive>
        <Files>
          <FileComparison>
            <Filename>C:\file1.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
          </FileComparison>
          <FileComparison>
            <Filename>C:\file3.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
          </FileComparison>
        </Files>
    </OperatorStation>
    <OperatorStation>
        <Name>OS2</Name>
        <OS>Microsoft Windows XP Professional</OS>
        <IP>172.20.254.91</IP>
        <Version>5.1.2600</Version>
        <Alive>true</Alive>
        <Files>
          <FileComparison>
            <Filename>C:\file1.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
          </FileComparison>
          <FileComparison>
            <Filename>C:\file2.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
          </FileComparison>
        </Files>
  </OperatorStation>
</ArrayOfOperatorStation>

并希望在最终的html结果中生成不同的数据表。

Operator staion
----------------
OS1     |  OS2
Alive   |  Alive

and another one with a filelist
OS1    | OS2    | etc...
---------------------------
File1  | File1
File3  | File2

我无法制作第二个列表,我不知道如何开始。完全用“查询”。

1 个答案:

答案 0 :(得分:1)

以下是您的第二张表的解决方案。其中还考虑了OperatorStation的文件数量可能不同的可能性。

尝试这样的事情:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*" />
    <xsl:output method="xml" indent="yes"/>

    <xsl:key name="kOperatorStationFiles" match="FileComparison"  use="../preceding-sibling::OperatorStation[1]/Name" />

    <xsl:template match="OperatorStation" mode="files">
        <xsl:param name="fileNr" />
        <td>
            <xsl:value-of select="key('kOperatorStationFiles', Name)[$fileNr]/Filename"/>
        </td>
    </xsl:template>

    <xsl:template match="OperatorStation" mode="header">
        <td>
            <xsl:value-of select="Name"/>
        </td>
    </xsl:template>

    <xsl:template match="/">
        <table>
            <tr>
                <xsl:apply-templates select="//OperatorStation" mode="header"/>
            </tr>
            <!-- find max files -->
            <xsl:for-each select="//OperatorStation" >
                <xsl:sort select="count(key('kOperatorStationFiles', Name))" order="descending" />
                <xsl:if test="position()=1">
                    <xsl:for-each select="key('kOperatorStationFiles', Name)" >
                        <tr>
                        <xsl:apply-templates select="//OperatorStation" mode="files">
                            <xsl:with-param name="fileNr" select="position()" />
                        </xsl:apply-templates>
                        </tr>
                    </xsl:for-each>
                </xsl:if>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

使用此(已更改)输入:

<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfOperatorStation>
    <OperatorStation>
        <Name>OS1</Name>
        <OS>Microsoft Windows XP Professional</OS>
        <IP>172.20.254.90</IP>
        <Version>5.1.2600</Version>
        <Alive>true</Alive>
    </OperatorStation>
    <Files>
        <FileComparison>
            <Filename>C:\file1.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
        </FileComparison>
        <FileComparison>
            <Filename>C:\file3.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
        </FileComparison>
    </Files>

    <OperatorStation>
        <Name>OS2</Name>
        <OS>Microsoft Windows XP Professional</OS>
        <IP>172.20.254.91</IP>
        <Version>5.1.2600</Version>
        <Alive>true</Alive>
    </OperatorStation>
    <Files>
        <FileComparison>
            <Filename>C:\file1.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
        </FileComparison>
        <FileComparison>
            <Filename>C:\file2.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
        </FileComparison>
        <FileComparison>
            <Filename>C:\file471.txt</Filename>
            <Hash>82c7aa19c690bb41e91c6b71d22bb533</Hash>
        </FileComparison>

    </Files>
</ArrayOfOperatorStation>

它会生成以下输出:

<?xml version="1.0"?>
<table>
  <tr>
    <td>OS1</td>
    <td>OS2</td>
  </tr>
  <tr>
    <td>C:\file1.txt</td>
    <td>C:\file1.txt</td>
  </tr>
  <tr>
    <td>C:\file3.txt</td>
    <td>C:\file2.txt</td>
  </tr>
  <tr>
    <td/>
    <td>C:\file471.txt</td>
  </tr>
</table>

更新: 由于评论“文件必须包含在-parent。中” 一些小的改动会做:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*" />
    <xsl:output method="xml" indent="yes"/>

    <xsl:key name="kOperatorStationFiles" match="FileComparison"  use="ancestor::OperatorStation/Name" />

    <xsl:template match="OperatorStation" mode="files">
        <xsl:param name="fileNr" />
        <td>
            <xsl:value-of select="key('kOperatorStationFiles', Name)[$fileNr]/Filename"/>
        </td>

    </xsl:template>

    <xsl:template match="OperatorStation" mode="header">
        <td>
            <xsl:value-of select="Name"/>
        </td>
    </xsl:template>

    <xsl:template match="/*">
        <table>
            <tr>
                <xsl:apply-templates select="/*/OperatorStation" mode="header"/>

            </tr>
            <!-- find max files -->
            <xsl:for-each select="/*/OperatorStation" >
                <xsl:sort select="count(key('kOperatorStationFiles', Name))" order="descending" />
                <xsl:if test="position()=1">
                    <xsl:for-each select="key('kOperatorStationFiles', Name)" >
                        <tr>
                        <xsl:apply-templates select="/*/OperatorStation" mode="files">
                            <xsl:with-param name="fileNr" select="position()" />
                        </xsl:apply-templates>
                        </tr>
                    </xsl:for-each>

                </xsl:if>
            </xsl:for-each>
        </table>
    </xsl:template>

</xsl:stylesheet>