1

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.

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Tim, I had tried nesting them together but I missed the point where I had to change the xpath expression. Admittedly I spent the bulk of my time researching and trying to implement for-each-group. This got me looking back in the right direction and the code runs through nicely. Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.