使用xml和xslt对输出进行分组 [英] grouping output with xml and xslt

查看:115
本文介绍了使用xml和xslt对输出进行分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多个team元素的XML文件.每个team元素都有多个player子元素.

基本结构如下

<league>
      <team>
          <!-- Team details go here -->
             <player>
                      <!-- Player details go here -->
             </player>
      </team>
</league>

我需要的输出是要显示球队的详细信息,然后是球员的表格.应当按姓氏对球员进行排序,按名字对球队进行排序.

我得到的是球队的所有细节,一个接一个,接着是所有球员的详细信息.

为了简化阅读,我将以下xml简化为仅一些细节.

这是我的xml

<league xmlns:xlink="http://www.w3.org/1999/xlink">

    <team>

        <teamName>Southampton</teamName>
        <manager>Ronald Koeman</manager>
        <stadium>St. Mary's</stadium>

        <players>

            <firstName>Victor</firstName>
            <surname>Wanyama</surname>
            <squadNumber>12</squadNumber>

        </players>

        <players>

            <firstName>Shane</firstName>
            <surname>Long</surname>
            <squadNumber>7</squadNumber>
        </players>

    </team>

        <team>

        <teamName>Arsenal</teamName>
        <manager>Arsene Wenger</manager>
        <stadium>Emirates Stadium</stadium>

        <players>

            <firstName>Hector</firstName>
            <surname>Bellerin</surname>
            <squadNumber>24</squadNumber>

        </players>

        <players>

            <firstName>Santi</firstName>
            <surname>Cazorla</surname>
            <squadNumber>19</squadNumber>
        </players>

    </team>
</league>

和xslt

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

<xsl:template match="/">
<html>

<head>
    <link rel="stylesheet" type="text/css" href="epl.css" />
</head>

<body>
    <xsl:for-each select="league/team">
    <xsl:sort select="teamName"/>

    <b>Name</b>
    <p><xsl:value-of select="teamName" /></p>

    <b>Manager</b>
    <p><xsl:value-of select="manager" /></p>

    <b>Stadium</b>
    <p><xsl:value-of select="Stadium" /></p>
    </xsl:for-each>

    <tr>
        <th>First Name</th>
        <th>Surname</th>
        <th>Squad Number</th>
    </tr>

    <xsl:for-each select="league/team/players">
    <xsl:sort select="surname"/>
    <tr>
    <td><xsl:value-of select="firstName"/></td>
    <td><xsl:value-of select="surname"/></td>
    <td><xsl:value-of select="squadNumber"/></td>
    </tr>
    </xsl:for-each>

</body>

</html>
</xsl:template>
</xsl:stylesheet>

我没有足够的代表来显示我所获得的图像,只是将我希望按球队分组的数据以及与每个球队相关的球员数据都在下面的表格中.

我尝试过的事情.

我尝试以各种方式使用for-each-group.所有这些都会导致出现一个通用的错误:加载样式表:解析XSLT样式表失败."在Firefox中.

<xsl:for-each-group select="league" group-by="@team"> <team name="{current-grouping-key()}"> </xsl:for-each-group

这包括将for-each-group放置在正文的开头,自己的xsl:template和主xsl:template中.

我已经为选择"部分尝试了其他xpath表达式.像league/teamleagueleague/

我已经尝试将xsl嵌套在一起,以便将球员和球队的数据收集到另一个for 中.

我安装了用于notepad ++的XML Tools插件,并且在尝试保存文件时得到: 第51行的XML解析错误: 样式表第3行中的数据标签过早结束

第51行的结尾为</xsl:stylesheet>

一旦我删除了for-each-group,它通常会保存,但是输出顺序不正确,就像我之前提到的那样.显示所有球队数据,然后显示所有球员数据,而不会将球员与自己表中的球队相关联.

解决方案

我认为您不需要在XSLT中进行分组,因为您的球员数据已经按团队在XML中进行了分组.您所需要做的就是移动当前选择球员的xsl:for-each,使其嵌套在当前选择球队的球员中,并调整select语句,使xpath表达式相对于当前team元素. >

尝试使用此XSLT

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

<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

<xsl:template match="/">
    <html>
    <head>
        <link rel="stylesheet" type="text/css" href="epl.css" />
    </head>
    <body>
        <xsl:for-each select="league/team">
        <xsl:sort select="teamName"/>
            <b>Name</b>
            <p><xsl:value-of select="teamName" /></p>
            <b>Manager</b>
            <p><xsl:value-of select="manager" /></p>
            <b>Stadium</b>
            <p><xsl:value-of select="stadium" /></p>
            <table>
            <tr>
                <th>First Name</th>
                <th>Surname</th>
                <th>Squad Number</th>
            </tr>
            <xsl:for-each select="players">
            <xsl:sort select="surname"/>
                <tr>
                <td><xsl:value-of select="firstName"/></td>
                <td><xsl:value-of select="surname"/></td>
                <td><xsl:value-of select="squadNumber"/></td>
                </tr>
            </xsl:for-each>
            </table>
            <br />
        </xsl:for-each>
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

I have an XML file with multiple team elements. Each team element has multiple player child elements.

The basic structure is as follows

<league>
      <team>
          <!-- Team details go here -->
             <player>
                      <!-- Player details go here -->
             </player>
      </team>
</league>

The output I need is for the team details to be displayed, followed by the players in a table. Players should be sorted by surname, teams by their name.

What I'm getting instead is all of the team's details one after another, followed by all players details in a single table.

I have simplified the following xml to only a few details to make it easier to read.

This is my xml

<league xmlns:xlink="http://www.w3.org/1999/xlink">

    <team>

        <teamName>Southampton</teamName>
        <manager>Ronald Koeman</manager>
        <stadium>St. Mary's</stadium>

        <players>

            <firstName>Victor</firstName>
            <surname>Wanyama</surname>
            <squadNumber>12</squadNumber>

        </players>

        <players>

            <firstName>Shane</firstName>
            <surname>Long</surname>
            <squadNumber>7</squadNumber>
        </players>

    </team>

        <team>

        <teamName>Arsenal</teamName>
        <manager>Arsene Wenger</manager>
        <stadium>Emirates Stadium</stadium>

        <players>

            <firstName>Hector</firstName>
            <surname>Bellerin</surname>
            <squadNumber>24</squadNumber>

        </players>

        <players>

            <firstName>Santi</firstName>
            <surname>Cazorla</surname>
            <squadNumber>19</squadNumber>
        </players>

    </team>
</league>

And the xslt

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

<xsl:template match="/">
<html>

<head>
    <link rel="stylesheet" type="text/css" href="epl.css" />
</head>

<body>
    <xsl:for-each select="league/team">
    <xsl:sort select="teamName"/>

    <b>Name</b>
    <p><xsl:value-of select="teamName" /></p>

    <b>Manager</b>
    <p><xsl:value-of select="manager" /></p>

    <b>Stadium</b>
    <p><xsl:value-of select="Stadium" /></p>
    </xsl:for-each>

    <tr>
        <th>First Name</th>
        <th>Surname</th>
        <th>Squad Number</th>
    </tr>

    <xsl:for-each select="league/team/players">
    <xsl:sort select="surname"/>
    <tr>
    <td><xsl:value-of select="firstName"/></td>
    <td><xsl:value-of select="surname"/></td>
    <td><xsl:value-of select="squadNumber"/></td>
    </tr>
    </xsl:for-each>

</body>

</html>
</xsl:template>
</xsl:stylesheet>

I don't have enough rep to show images of what I'm getting but simply put I want the data grouped by the teams, with the player data relevant to each team in a table below that.

What I've tried.

I've tried using for-each-group in various ways. All resulting in a generic " Error loading stylesheet: Parsing an XSLT stylesheet failed." in firefox.

<xsl:for-each-group select="league" group-by="@team"> <team name="{current-grouping-key()}"> </xsl:for-each-group

This includes placing for-each-group in the beginning of the body, in it's own xsl:template, in the main xsl:template.

I've tried alternate xpath expressions for the "select" part. Like league/team, league, league/

I've tried nesting the xsl that gets the player and team data together into another for-each

I have XML Tools plugin for notepad++ installed and when trying to save the file I get: XML parsing erro at line 51: Premature end of data tag in stylesheet line 3

Line 51 only has the closing </xsl:stylesheet>

Once I remove the for-each-group it saves normally but output sequence is incorrect and as I mentioned before. All team data is shown, followed by all player data without associating players with teams in their own tables.

解决方案

I don't think you need to do grouping in your XSLT, as your player data is already grouped by team in your XML. All you need to do is move the xsl:for-each that current selects players so that is nested in the one that current selects the teams, and adjust the select statement so that the xpath expression is relative to the current team element.

Try this XSLT

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

<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />

<xsl:template match="/">
    <html>
    <head>
        <link rel="stylesheet" type="text/css" href="epl.css" />
    </head>
    <body>
        <xsl:for-each select="league/team">
        <xsl:sort select="teamName"/>
            <b>Name</b>
            <p><xsl:value-of select="teamName" /></p>
            <b>Manager</b>
            <p><xsl:value-of select="manager" /></p>
            <b>Stadium</b>
            <p><xsl:value-of select="stadium" /></p>
            <table>
            <tr>
                <th>First Name</th>
                <th>Surname</th>
                <th>Squad Number</th>
            </tr>
            <xsl:for-each select="players">
            <xsl:sort select="surname"/>
                <tr>
                <td><xsl:value-of select="firstName"/></td>
                <td><xsl:value-of select="surname"/></td>
                <td><xsl:value-of select="squadNumber"/></td>
                </tr>
            </xsl:for-each>
            </table>
            <br />
        </xsl:for-each>
    </body>
    </html>
</xsl:template>
</xsl:stylesheet>

这篇关于使用xml和xslt对输出进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆