niyut
niyut

Reputation: 23

xml to xml conversion using XSTL

I have an input xml file named copystud.xml:

            <!-- New XML document created with EditiX XML Editor 
            (http://www.editix.com) at Thu Aug 31 20:55:30 IST 2017 -->


       <?xml-stylesheet type="text/xsl" href="copystudent.xsl"?>
      <player>
       <name>niyut</name>
       <score>
          <game1>95</game1>
          <game2>70</game2>
          <game3>80</game3>
          </score>
       </player>

I need the output like this :

    <outcome>
<playername>niyut</playername> 
<total>237</total> 
<maxscore>300</maxscore>
 <nextlevel>congrats for next level</nextlevel> 
</outcome>

and xsl file copystudent.xsl:

     <?xml version="1.0" encoding="UTF-8" ?>

<!-- New XSLT document created with EditiX XML Editor (http://www.editix.com) at Fri Sep 01 11:48:27 IST 2017 -->

<xsl:stylesheet version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
    xmlns:err="http://www.w3.org/2005/xqt-errors"
    exclude-result-prefixes="xs xdt err○ fn">

    <xsl:output method="html" indent="yes"/>

    <xsl:template match="/">

        <html>
            <body>
                Evaluating players
                <table>
                      <tr>
                        <td>totalscore</td>
                        <td>
                            <xsl:variable name ="tot_score" select="sum(.//game1 | .//game2 | .//game3)" />
                            <xsl:value-of select="$tot_score" />

                        </td>

                        <td>maxscore</td>
                        <td>
                        <xsl:variable name="subj_count" select="count(/player/score/*)"/>
                            <xsl:value-of select="count(/player/score/*)*100"/>
                        </td>

                        <td>evalv</td>
                            <td>
                                <xsl:value-of select="$tot_score div $subj_count" />
                            </td>
                            </tr>
                    </table>
            </body>
        </html>

        <xsl:apply-templates/>
    </xsl:template>


</xsl:stylesheet>

I can't find the average score of players and then to display whether he is going to next level or not. The max_score for each game is 100.

I need xml to xml transformation and not html. Please guide me to solve this.

Upvotes: 0

Views: 1720

Answers (2)

Aniket V
Aniket V

Reputation: 3247

i need xml to xml transformation and not html

For XML as an output, you can use the below XSL to transform the input XML. Comments have been added in the XSL for reference.

XSLT

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

    <!-- points to the player node in the input XML -->
    <xsl:template match="player">
        <!-- variable for storing the total score of the player. Sums all the values from child nodes of score -->
        <xsl:variable name="totalScore" select="sum(score/*)" />
        <!-- variable for storing the game count. Counts the child nodes of score -->
        <xsl:variable name="gameCnt" select="count(score/*)" />
        <!-- variable for storing the average score of the player. Format the output to 2 decimals -->
        <xsl:variable name="avgScore" select="format-number($totalScore div $gameCnt, '0.##')" />
        <outcome>
            <playername>
                <xsl:value-of select="name" /> 
            </playername>
            <total>
                <xsl:value-of select="$totalScore" />
            </total>
            <maxscore>
                <xsl:value-of select="$gameCnt * 100" />
            </maxscore>
            <nextLevel>
                <!-- condition for providing message -->
                <xsl:choose>
                    <!-- condition checks average score greater than 50 -->
                    <xsl:when test="$avgScore &gt; 50">
                        <xsl:value-of select="'congrats for next level'" />
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="'keep trying'" />
                    </xsl:otherwise>
                </xsl:choose>
            </nextLevel>
        </outcome>
    </xsl:template>
</xsl:stylesheet>

XML Output

<outcome>
    <playername>niyut</playername>
    <total>245</total>
    <maxscore>300</maxscore>
    <nextLevel>congrats for next level</nextLevel>
</outcome>

Upvotes: 0

Tim C
Tim C

Reputation: 70598

Variables in XSLT are locally scoped to the block in which they are declared. You need to move the variable declarations to the start of the template, and then they can be used anywhere within the template

Try this XSLT. Note I have changed the template to match player as that then simplifies the XPath expressions in the code

<xsl:stylesheet version="1.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" indent="yes"/>

    <xsl:template match="/player">
        <xsl:variable name ="tot_score" select="sum(score/*)" />
        <xsl:variable name="subj_count" select="count(score/*)"/>
        <html>
            <body>
                Evaluating players
                <table>
                      <tr>
                        <td>totalscore</td>
                        <td>
                            <xsl:value-of select="$tot_score" />
                        </td>
                        <td>maxscore</td>
                        <td>
                            <xsl:value-of select="$subj_count * 100"/>
                        </td>
                        <td>evalv</td>
                        <td>
                            <xsl:value-of select="format-number($tot_score div $subj_count, '0.##')" />
                        </td>
                    </tr>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 1

Related Questions