XSLT:使用一个密钥交叉引用第二个密钥

时间:2017-07-14 16:21:59

标签: xml xslt key xmltable

我需要将XML转换为表格网格,格式为:

A1,B1,C1

A2,B2,C2

A3,B3,C3

我正在使用的XML为每条记录提供一个单元格值,但每条记录都提供DayOfWeek(列)和Stream(行)值。

我使用两个键进行了简单的XSLT转换,一个用于Stream,另一个用于DayOfWeek。这些工作成功,因为我有3行,每行一个,3列,一周中的每一天。然而,内容只是重复的第一行(即

A1,B1,C1,
A1,B1,C1,
A1,B1,C1

如何根据两个关键标准将DisplayStuff选择到表格单元格中?

这是我的XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes" encoding="us-ascii" />
    <xsl:key name="DayOfWeek1" match="DataRow" use="DayOfWeek" />
    <xsl:key name="Stream1" match="DataRow" use="Stream" />
    <xsl:template match="QueryResults">
        <table>
    <xsl:for-each select="//DataRow[generate-id() = generate-id(key('Stream1',Stream)[1])]">
        <tr style="border: 1px solid black;" class="scrolling">
            <xsl:for-each select="//DataRow[generate-id() = generate-id(key('DayOfWeek1',DayOfWeek)[1])]">


                <td style="border: 1px solid black;" width="100px">
                    <xsl:value-of select="DisplayStuff" />
                </td>

            </xsl:for-each>
        </tr>
    </xsl:for-each>
    </table>
    </xsl:template>
</xsl:stylesheet>

XML:

<?xml version="1.0" encoding="UTF-8"?>
<QueryResults>
<DataRow>
    <Stream>1</Stream>
    <DayOfWeek>1</DayOfWeek>
    <DisplayStuff>A1</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>1</Stream>
    <DayOfWeek>2</DayOfWeek>
    <DisplayStuff>B1</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>1</Stream>
    <DayOfWeek>3</DayOfWeek>
    <DisplayStuff>C1</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>2</Stream>
    <DayOfWeek>1</DayOfWeek>
    <DisplayStuff>A2</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>2</Stream>
    <DayOfWeek>2</DayOfWeek>
    <DisplayStuff>B2</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>2</Stream>
    <DayOfWeek>3</DayOfWeek>
    <DisplayStuff>C2</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>3</Stream>
    <DayOfWeek>1</DayOfWeek>
    <DisplayStuff>A3</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>3</Stream>
    <DayOfWeek>2</DayOfWeek>
    <DisplayStuff>B3</DisplayStuff>
</DataRow>
<DataRow>
    <Stream>3</Stream>
    <DayOfWeek>3</DayOfWeek>
    <DisplayStuff>C3</DisplayStuff>
</DataRow>
</QueryResults>

1 个答案:

答案 0 :(得分:0)

以这种方式试试吗?

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="row-by-day" match="DataRow" use="DayOfWeek" />
<xsl:key name="row-by-stream" match="DataRow" use="Stream" />

<xsl:template match="/QueryResults">
    <!-- a column for each distinct day of week  -->
    <xsl:variable name="columns" select="DataRow[generate-id() = generate-id(key('row-by-day', DayOfWeek)[1])]" />
    <table border="1">
        <!--  a row for each distinct stream -->
        <xsl:for-each select="DataRow[generate-id() = generate-id(key('row-by-stream', Stream)[1])]">
            <xsl:variable name="stream" select="key('row-by-stream', Stream)" />
            <tr>
                <!-- a cell for each column -->
                <xsl:for-each select="$columns">
                    <xsl:sort select="DayOfWeek" data-type="number" order="ascending"/>
                    <td>
                        <xsl:value-of select="$stream[DayOfWeek = current()/DayOfWeek]/DisplayStuff" />
                    </td>
                </xsl:for-each>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

请注意,这假设DataRowStream的每个交叉点最多只有一个DayOfWeek