views:

216

answers:

2

I have converted mny stylesheet to use apply templates instead of call templates and it worked fine for my other styesheet, which was more complicated, but this one doesn't seem to work even thought it is a much simpler template.

All that it outputs is the sex node and the userlevel node. I think it has to do with my Xpath.

All i want is to output the < user > information, nothing else

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

    <xsl:template name="hoo" match="/">
        <html>
            <head>
                <title>Registered Members</title>
                <link rel="stylesheet" type="text/css" href="user.css" />
            </head>
            <body>
                <h1>Registered Members</h1>
                <xsl:for-each select="folktask/member/user">

                    <div class="userdiv">

                        <xsl:apply-templates/>

                    </div>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="folktask/member/user">
        <xsl:apply-templates select="@id"/>
        <xsl:apply-templates select="personal/name"/>
        <xsl:apply-templates select="personal/address1"/>
        <xsl:apply-templates select="personal/city"/>
        <xsl:apply-templates select="personal/county"/>
        <xsl:apply-templates select="personal/postcode"/>
        <xsl:apply-templates select="personal/telephone"/>
        <xsl:apply-templates select="personal/mobile"/>
        <xsl:apply-templates select="personal/email"/>
        <xsl:apply-templates select="personal"/>
        <xsl:apply-templates select="account/username"/>
        <xsl:apply-templates select="account"/>
    </xsl:template>

    <xsl:template match="@id">
        <div class="heading bold"><h2>USER ID: <xsl:value-of select="." /></h2></div>
    </xsl:template>

    <xsl:template match="personal/name">
        <div class="small bold">NAME:</div> 
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/address1">
        <div class="small bold">ADDRESS:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/city">
        <div class="small bold">CITY:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/county">
        <div class="small bold">COUNTY:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/postcode">
        <div class="small bold">POSTCODE:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/telephone">
        <div class="small bold">TELEPHONE:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/mobile">
        <div class="small bold">MOBILE:</div>
        <div class="large"><xsl:value-of select="." />
        </div>
    </xsl:template>

    <xsl:template match="personal/email">
        <div class="small bold">EMAIL:</div>
        <div class="large">
            <xsl:element name="a">
                <xsl:attribute name="href">
                    <xsl:text>mailto:</xsl:text>
                    <xsl:value-of select="." />
                </xsl:attribute>
                <xsl:value-of select="." />
            </xsl:element>
        </div>
    </xsl:template>

    <xsl:template match="personal">
    <div class="small bold">SEX:</div>
    <div class="colored bold">
        <xsl:choose>
            <xsl:when test="sex='Male'">
                <div class="sex male"><xsl:value-of select="sex/."/></div>
            </xsl:when>
            <xsl:otherwise>
                <div class="sex female"><xsl:value-of select="sex/."/></div>
            </xsl:otherwise>
        </xsl:choose>
    </div>
    </xsl:template>

    <xsl:template match="account/username">
        <div class="small bold">USERNAME:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>


    <xsl:template match="account">
        <div class="small bold">ACCOUNT TYPE:</div>
        <div class="colored ">
        <xsl:choose>
            <xsl:when test="userlevel='1'">
                <div class="nml bold">Normal User</div>
            </xsl:when>

            <xsl:when test="userlevel='2'">
                <div class="vol bold">Volunteer</div>
            </xsl:when>

            <xsl:when test="userlevel='3'">
                <div class="org bold">Organiser</div>
            </xsl:when>

            <xsl:otherwise>
                <div class="name adm bold">Administrator</div>
            </xsl:otherwise>
        </xsl:choose>
        </div>
    </xsl:template>

</xsl:stylesheet> 

and some of my xml

<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="users.xsl"?>
<folktask xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="folktask.xsd">
    <member>
        <user id="1">
            <personal>
                <name>Abbie Hunt</name>
                <sex>Female</sex>
                <address1>108 Access Road</address1>
                <address2></address2>
                <city>Wells</city>
                <county>Somerset</county>
                <postcode>BA5 8GH</postcode>
                <telephone>01528927616</telephone>
                <mobile>07085252492</mobile>
                <email>[email protected]</email>
            </personal>
            <account>
                <username>AdRock</username>
                <password>269eb625e2f0cf6fae9a29434c12a89f</password>
                <userlevel>4</userlevel>
                <signupdate>2010-03-26T09:23:50</signupdate>
            </account>
        </user>
        <volunteer id="1">
            <roles></roles>
            <region>South West</region>
        </volunteer>
    </member>
    <member>
        <user id="2">
            <personal>
                <name>Aidan Harris</name>
                <sex>Male</sex>
                <address1>103 Aiken Street</address1>
                <address2></address2>
                <city>Chichester</city>
                <county>Sussex</county>
                <postcode>PO19 4DS</postcode>
                <telephone>01905149894</telephone>
                <mobile>07784467941</mobile>
                <email>[email protected]</email>
            </personal>
            <account>
                <username>AmbientExpert</username>
                <password>8e64214160e9dd14ae2a6d9f700004a6</password>
                <userlevel>2</userlevel>
                <signupdate>2010-03-26T09:23:50</signupdate>
            </account>
        </user>
        <volunteer id="2">
            <roles>Van Driver,gas Fitter</roles>
            <region>South Central</region>
        </volunteer>
    </member>
</folktask>
A: 

There are many errors. The main are the following:

  • You cannot apply template to attribute
  • If you write <xsl:apply-templates select="personal/name"/>, you might write <xsl:template match="name"> to match it. (And also for other nodes)
darja
There is absolutely no reason why you can't use apply-templates for an attribute. In fact the built-in templates do precisely that. I'd agree that in this case the "personal/name" and so on are excessive but there are often very good reasons for using longer paths.
Nic Gibson
I really didn't know that apply-templates can be used with attributes. Thanks for new information. But I still see no sense in it.And about longer path - I have meant current situation, not all.
darja
+2  A: 

The problem is in this code:

   <xsl:for-each select="folktask/member/user">

        <div class="userdiv">

            <xsl:apply-templates/>

        </div>
    </xsl:for-each>

This applies templates to all children of the current user element -- not to the user element.

As result, the template matching user is not selected.

The children of user are personal and account.

The templates matching these elements are selected and they produce their output.

Solution: Quite some cleanup is necessary, but the first obvious step is to replace the above code with:

        <xsl:apply-templates select="folktask/member/user"/>

You'll also have to move the div from the deleted body of <xsl:for-each> into the template matching folktask/member/user.

The corrected XSLT code is:

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

    <xsl:template name="hoo" match="/">
        <html>
            <head>
                <title>Registered Members</title>
                <link rel="stylesheet" type="text/css" href="user.css" />
            </head>
            <body>
                <h1>Registered Members</h1>
                <xsl:apply-templates select="folktask/member/user"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="folktask/member/user">
        <div class="userdiv">
            <xsl:apply-templates select="@id"/>
            <xsl:apply-templates select="personal/name"/>
            <xsl:apply-templates select="personal/address1"/>
            <xsl:apply-templates select="personal/city"/>
            <xsl:apply-templates select="personal/county"/>
            <xsl:apply-templates select="personal/postcode"/>
            <xsl:apply-templates select="personal/telephone"/>
            <xsl:apply-templates select="personal/mobile"/>
            <xsl:apply-templates select="personal/email"/>
            <xsl:apply-templates select="personal"/>
            <xsl:apply-templates select="account/username"/>
            <xsl:apply-templates select="account"/>
        </div>
    </xsl:template>

    <xsl:template match="@id">
        <div class="heading bold"><h2>USER ID: <xsl:value-of select="." /></h2></div>
    </xsl:template>

    <xsl:template match="personal/name">
        <div class="small bold">NAME:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/address1">
        <div class="small bold">ADDRESS:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/city">
        <div class="small bold">CITY:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/county">
        <div class="small bold">COUNTY:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/postcode">
        <div class="small bold">POSTCODE:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/telephone">
        <div class="small bold">TELEPHONE:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>

    <xsl:template match="personal/mobile">
        <div class="small bold">MOBILE:</div>
        <div class="large"><xsl:value-of select="." />
        </div>
    </xsl:template>

    <xsl:template match="personal/email">
        <div class="small bold">EMAIL:</div>
        <div class="large">
            <xsl:element name="a">
                <xsl:attribute name="href">
                    <xsl:text>mailto:</xsl:text>
                    <xsl:value-of select="." />
                </xsl:attribute>
                <xsl:value-of select="." />
            </xsl:element>
        </div>
    </xsl:template>

    <xsl:template match="personal">
    <div class="small bold">SEX:</div>
    <div class="colored bold">
        <xsl:choose>
            <xsl:when test="sex='Male'">
                <div class="sex male"><xsl:value-of select="sex/."/></div>
            </xsl:when>
            <xsl:otherwise>
                <div class="sex female"><xsl:value-of select="sex/."/></div>
            </xsl:otherwise>
        </xsl:choose>
    </div>
    </xsl:template>

    <xsl:template match="account/username">
        <div class="small bold">USERNAME:</div>
        <div class="large"><xsl:value-of select="." /></div>
    </xsl:template>


    <xsl:template match="account">
        <div class="small bold">ACCOUNT TYPE:</div>
        <div class="colored ">
        <xsl:choose>
            <xsl:when test="userlevel='1'">
                <div class="nml bold">Normal User</div>
            </xsl:when>

            <xsl:when test="userlevel='2'">
                <div class="vol bold">Volunteer</div>
            </xsl:when>

            <xsl:when test="userlevel='3'">
                <div class="org bold">Organiser</div>
            </xsl:when>

            <xsl:otherwise>
                <div class="name adm bold">Administrator</div>
            </xsl:otherwise>
        </xsl:choose>
        </div>
    </xsl:template>

</xsl:stylesheet>

Running the corrected transformation now produces the intended results:

<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<title>Registered Members</title>
<link rel="stylesheet" type="text/css" href="user.css">
</head>
<body>
<h1>Registered Members</h1>
<div class="userdiv">
<div class="heading bold"><h2>USER ID: 1</h2></div>
<div class="small bold">NAME:</div>
<div class="large">Abbie Hunt</div>
<div class="small bold">ADDRESS:</div>
<div class="large">108 Access Road</div>
<div class="small bold">CITY:</div>
<div class="large">Wells</div>
<div class="small bold">COUNTY:</div>
<div class="large">Somerset</div>
<div class="small bold">POSTCODE:</div>
<div class="large">BA5 8GH</div>
<div class="small bold">TELEPHONE:</div>
<div class="large">01528927616</div>
<div class="small bold">MOBILE:</div>
<div class="large">07085252492</div>
<div class="small bold">EMAIL:</div>
<div class="large"><a href="mailto:[email protected]">[email protected]</a></div>
<div class="small bold">SEX:</div>
<div class="colored bold">
<div class="sex female">Female</div>
</div>
<div class="small bold">USERNAME:</div>
<div class="large">AdRock</div>
<div class="small bold">ACCOUNT TYPE:</div>
<div class="colored ">
<div class="name adm bold">Administrator</div>
</div>
</div>
<div class="userdiv">
<div class="heading bold"><h2>USER ID: 2</h2></div>
<div class="small bold">NAME:</div>
<div class="large">Aidan Harris</div>
<div class="small bold">ADDRESS:</div>
<div class="large">103 Aiken Street</div>
<div class="small bold">CITY:</div>
<div class="large">Chichester</div>
<div class="small bold">COUNTY:</div>
<div class="large">Sussex</div>
<div class="small bold">POSTCODE:</div>
<div class="large">PO19 4DS</div>
<div class="small bold">TELEPHONE:</div>
<div class="large">01905149894</div>
<div class="small bold">MOBILE:</div>
<div class="large">07784467941</div>
<div class="small bold">EMAIL:</div>
<div class="large"><a href="mailto:[email protected]">[email protected]</a></div>
<div class="small bold">SEX:</div>
<div class="colored bold">
<div class="sex male">Male</div>
</div>
<div class="small bold">USERNAME:</div>
<div class="large">AmbientExpert</div>
<div class="small bold">ACCOUNT TYPE:</div>
<div class="colored ">
<div class="vol bold">Volunteer</div>
</div>
</div>
</body>
</html>
Dimitre Novatchev
What is the other cleanup you are on about. I tried your suggestion but i get no data at all, just the empty divs which should hold the data
AdRock
@AdRock: I have provided the complete result from the transformation. You can see that all user information is in the output.
Dimitre Novatchev
I am totally lost. This was working earlier wthout the user id and i see what you mean about the uer id not being a child element but now i'm confused to what goes where. Do i leave the apply-templates where it is and move the for-each inside the template matching folktask/member/user. This is probably so obvious but i can't see it
AdRock
You just have to replace the problematic code (see my answer) with the proposed replacement (again in my answer). Then you'll get the result I've placed in my answer. This is a very simple exercise.
Dimitre Novatchev
@AdRock: I placed the whole text of the corrected transformation in my answer. Just run it on your provided XML and you must get the same result as the one in my answer.
Dimitre Novatchev
Thanks....i didn't realise i could have done it without the for-each
AdRock
@AdRock: Actually it is a good recommended practice to try to avoid using xsl:for-each as much as possible -- it is very rarely needed.
Dimitre Novatchev