I have a large number of html files like the following:
<html>
<head>
<title>t</title>
</head>
<body>
<div class="a">
<div class="b" type="t1">
b11<div class="x">x</div>
b12<div class="y">y</div>b13
</div>
<div class="c">c</div>
</div>
<div class="b" type="t2" region="r">b21
<div class="x">x</div>b22
<div class="y">y</div>
b23
</div>
</body>
</html>
At present the text for div class="b" is fragmented at the beginning, middle and end of the node.
I want to consolidate the text for div class="b" so that it appears at the beginning.
The file I want to obtain is like the following:
<html>
<head>
<title>t</title>
</head>
<body>
<div class="a">
<div class="b" type="t1">b11 b12 b13
<div class="x">x</div>
<div class="y">y</div>
</div>
<div class="c">c</div>
</div>
<div class="b" type="t2" region="r">b21 b22 b23
<div class="x">x</div>
<div class="y">y</div>
</div>
</body>
</html>
I run the following bash script a.sh:
xsltproc a.xslt a.html > b.html
where a.xslt is the following:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//div[#class='b']">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
<xsl:for-each select="text()">
<xsl:if test="position() > 1"><xsl:text> </xsl:text></xsl:if>
<xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Unfortunately my output is not what I want:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>t</title>
</head>
<body>
<div class="a">
<div class="b" type="t1">b11
<div class="x">x</div>
b12
<div class="y">y</div>
b13</div>
b11 b12 b13
<div class="c">c</div>
</div>
<div class="b" region="r" type="t2">b21
<div class="x">x</div>
b22
<div class="y">y</div>
b23</div>
<p>b21 b22 b23</p>
</body>
</html>
Do you have any advice on how to proceed please?
Would this work for you?
<xsl:template match="div[#class='b']">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:for-each select="text()">
<xsl:if test="position() > 1">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space(.)"/>
</xsl:for-each>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
Related
I have a large number of html files with the following structure:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>t</title>
</head>
<body>
<div class="a">
<div class="i">i</div>
<div class="b">b1
<div class="b1">b11</div>
<div class="b2">b12</div>
</div>
<div class="j">j</div>
<div class="b">b2
<div class="b1">b21</div>
<div class="b2">b22</div>
</div>
<div class="k">k</div>
</div>
<div class="x">
<div class="i">i3</div>
<div class="b">b3
<div class="b1">b31</div>
<div class="b2">b32</div>
</div>
<div class="j">j3</div>
</div>
</body>
</html>
I would like to:
move all siblings of b inside b
remove parent a but keep its content
Please notice that:
div class="a" has not text()
div class="b" can have other parents apart from div class="a", for instance div class="x"
div class="a" can contain 1:N div class="b"
The output should be like the following:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
<title>t</title>
</head>
<body>
<div class="b">b1
<div class="b1">b11</div>
<div class="b2">b12</div>
<div class="i">i</div>
<div class="j">j</div>
<div class="k">k</div>
</div>
<div class="b">b2
<div class="b1">b21</div>
<div class="b2">b22</div>
<div class="i">i</div>
<div class="j">j</div>
<div class="k">k</div>
</div>
<div class="x">
<div class="i">i3</div>
<div class="b">b3
<div class="b1">b31</div>
<div class="b2">b32</div>
</div>
<div class="j">j3</div>
</div>
</body>
</html>
I am using a shell script similar to the following:
xsltproc a.xslt a.html > b.html
where a.xslt is as follows:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[#class='a']/div[#class='b']">
<xsl:apply-templates select="#*|preceding-sibling()[not(self::div[#class='b'])]"/>
<xsl:apply-templates select="#*|following-sibling()[not(self::div[#class='b'])]"/>
<xsl:copy-of select="div[#class='b']"/>
</xsl:template>
</xsl:stylesheet>
However I get an error, probably because I am not using preceding-sibling and following-sibling correctly:
xmlXPathCompOpEval: function preceding-sibling not found
Could you advise me on how to untangle this xslt please?
I believe this follows your instructions:
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="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove parent a but keep its content -->
<xsl:template match="div[#class='a']">
<xsl:apply-templates/>
</xsl:template>
<!-- move all siblings of b inside b -->
<xsl:template match="div[#class='b']">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
<xsl:copy-of select="../node()[not(self::div[#class='b'])]"/>
</xsl:copy>
</xsl:template>
<!-- do not process siblings of b -->
<xsl:template match="node()[../div[#class='b']][not(self::div[#class='b'])]"/>
</xsl:stylesheet>
However, the result is not what you show:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<title>t</title>
</head>
<body>
<div class="b">b1
<div class="b1">b11</div>
<div class="b2">b12</div>
<div class="i">i</div>
<div class="j">j</div>
<div class="k">k</div>
</div>
<div class="b">b2
<div class="b1">b21</div>
<div class="b2">b22</div>
<div class="i">i</div>
<div class="j">j</div>
<div class="k">k</div>
</div>
<div class="x">
<div class="b">b3
<div class="b1">b31</div>
<div class="b2">b32</div>
<div class="i">i3</div>
<div class="j">j3</div>
</div>
</div>
</body>
</html>
I have the following source a.html:
<html>
<head>
<title>title</title>
</head>
<body>
<div class="a">a
<div class="a1">a1</div>
<div class="x" type="typea2">x
<div class="x1">x1</div>
</div>
<div class="a3">a3</div>
</div>
<div class="b">b_1
<div class="b1">b1_1</div>
<div class="b3">b3_11</div>
<div class="b3">b3_12</div>
<div class="b3">b3_13</div>
</div>
<div class="b">b_2
<div class="b1">b1_2</div>
<div class="b3">b3_21</div>
<div class="b3">b3_22</div>
<div class="b">b_3
<div class="b1">b1_3</div>
<div class="b3">b3_31</div>
<div class="b3">b3_32</div>
<div class="b3">b3_33</div>
<div class="b3">b3_34</div>
</div>
</body>
</html>
I want to:
copy the element div class="x" inside each div class="b" after its own text and any div class="b1"
remove the original div class="x" from div class="a"
The output should be:
<html>
<head>
<title>title</title>
</head>
<body>
<div class="a">a
<div class="a1">a1</div>
<div class="a3">a3</div>
</div>
<div class="b">b_1
<div class="b1">b1_1</div>
<div class="x" type="typea2">x
<div class="x1">x1</div>
</div>
<div class="b3">b3_11</div>
<div class="b3">b3_12</div>
<div class="b3">b3_13</div>
</div>
<div class="b">b_2
<div class="b1">b1_2</div>
<div class="x" type="typea2">x
<div class="x1">x1</div>
</div>
<div class="b3">b3_21</div>
<div class="b3">b3_22</div>
<div class="b">b_3
<div class="b1">b1_3</div>
<div class="x" type="typea2">x
<div class="x1">x1</div>
</div>
<div class="b3">b3_31</div>
<div class="b3">b3_32</div>
<div class="b3">b3_33</div>
<div class="b3">b3_34</div>
</div>
</body>
</html>
I have used the following shell script a.sh:
xsltproc --html a.xslt a.html > b.html
with the following a.xslt:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- ignore x-inside-a -->
<xsl:template match="//div[#class='a']/div[#class='x']"/>
<!-- place the x-inside-a into each b after text() and b1 -->
<xsl:template match="div[#class='b']">
<xsl:copy>
<xsl:copy-of select="//div[#class='a']/div[#class='x']" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
However I am not getting the desired result?
Could I ask for your help please?
If the inner div is always present I would write a template for it:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<!-- ignore x-inside-a -->
<xsl:template match="div[#class='a']/div[#class='x']"/>
<!-- place the x-inside-a into each b after b1 -->
<xsl:template match="div[#class='b']/div[#class = 'b1']">
<xsl:call-template name="identity"/>
<xsl:copy-of select="//div[#class='a']/div[#class='x']" />
</xsl:template>
</xsl:stylesheet>
I have a large number of files with a structure like the following a.html:
<html>
<body>
<div class="a">aaa
<div class="b">bbb</div>
<div class="c">ccc1
<div class="d">ddd11
<div class="e">eee11</div>
<div class="f">fff11
<div class="g">ggg111</div>
<div class="g">ggg112</div>
<div class="g">ggg113</div>
<div class="g">ggg114</div>
<div class="g">ggg115</div>
<div class="g">ggg116</div>
</div>
</div>
</div>
<div class="c">ccc2
<div class="d">ddd21
<div class="e">eee21</div>
<div class="f">fff21
<div class="g">ggg211</div>
<div class="g">ggg212</div>
<div class="g">ggg213</div>
<div class="g">ggg214</div>
</div>
</div>
</div>
</div>
</body>
</html>
The number of div class="c" is a known single-digit integer, in this case it is equal to 2.
I would like to generate the files a_1.html and a_2.html, where each file contains the 1st and the 2nd occurrence of the div class="c" respectively.
In this example, I would like to generate a_1.html and a_2.html as follows:
a_1.html
<html>
<body>
<div class="a">aaa
<div class="b">bbb</div>
<div class="c">ccc1
<div class="d">ddd11
<div class="e">eee11</div>
<div class="f">fff11
<div class="g">ggg111</div>
<div class="g">ggg112</div>
<div class="g">ggg113</div>
<div class="g">ggg114</div>
<div class="g">ggg115</div>
<div class="g">ggg116</div>
</div>
</div>
</div>
</div>
</body>
</html>
a_2.html
<html>
<body>
<div class="a">aaa
<div class="b">bbb</div>
<div class="c">ccc2
<div class="d">ddd21
<div class="e">eee21</div>
<div class="f">fff21
<div class="g">ggg211</div>
<div class="g">ggg212</div>
<div class="g">ggg213</div>
<div class="g">ggg214</div>
</div>
</div>
</div>
</div>
</body>
</html>
I have a shell script like the following:
#!/bin/bash
for i in {1..2}
do
xsltproc --param occurrence ${i} a.xslt a.html > a_${i}.html
done
My a.xslt however does not extract just the i-th (first or second in this case) occurrence of div class="c".
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="occurrence"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[#class='a']">
<xsl:copy>
<xsl:apply-templates select="div[#class='a']" />
<xsl:apply-templates select="#* | div[#class='b'] | text()" />
<xsl:apply-templates select="div[#class='c']" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
How could I modify it to get the correct result?
Thank you in advance for you help.
If you need to stay with your current approach, you need only to change the call for select="div[#class='c'].
To:
<xsl:apply-templates select="div[#class='c'][position()=$occurrence]" />
But attention:
The <xsl:apply-templates select="div[#class='a']" /> before apply-templates for attributes (#*) is wrong.
Therefor try:
<xsl:template match="div[#class='a']">
<xsl:copy>
<xsl:apply-templates select="#* | div[#class='b'] | text()" />
<xsl:apply-templates select="div[#class='c'][position()=$occurrence]" />
</xsl:copy>
</xsl:template>
Use
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="occurrence"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div[#class='c']">
<xsl:variable name="pos">
<xsl:number count="div[#class = 'c']"/>
</xsl:variable>
<xsl:if test="$pos = $occurrence">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
I'm trying to do the following:
<body>
<div>
<p> text<note/>texttext<note/>text </p>
<p> text<note/>text </p>
</div>
<div>
text<note/>texttext<note/>text
</div>
</body>
should result in
<body>
<div>
<p> text<note n="1"/>texttext<note n="2"/>text </p>
<p> text<note n="3"/>text </p>
</div>
<div>
text<note n="1"/>texttext<note n="2"/>text
</div>
</body>
As you can see, I want to number all notes under div regardless of the parent node. So notes can be structured under div in any way.
However I can't figure out a solution by using xsl:number. Any help would be appreciated.
edit: Big thanks to DRCB for his solution. I've adapted it so that it can be also used for complex nesting by using an identity template.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="div//note">
<note>
<xsl:attribute name="n">
<xsl:value-of select="count(preceding::note) - count(preceding::div//note) + 1"/>
</xsl:attribute>
<xsl:value-of select="."/>
</note>
</xsl:template>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
tranforms:
<body>
<any>
<div>
<p>
<p> text<note/>texttext<note/>text </p>
</p>
<p> text<note/>text </p>
</div>
</any>
<div> text<note/>texttext<note/>text </div>
</body>
to:
<body>
<any>
<div>
<p>
<p> text<note n="1"/>texttext<note n="2"/>text </p>
</p>
<p> text<note n="3"/>text </p>
</div>
</any>
<div> text<note n="1"/>texttext<note n="2"/>text </div>
</body>
I believe there might be a better solution however this works for me.
A solution using xsl:number:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="note">
<xsl:variable name="vNum">
<xsl:number level="any" count="note" from="/*/div"/>
</xsl:variable>
<note n="{$vNum}">
<xsl:apply-templates/>
</note>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<body>
<div>
<p> text<note/>texttext<note/>text </p>
<p> text<note/>text </p>
</div>
<div>
text<note/>texttext<note/>text
</div>
</body>
the wanted, correct result is produced:
<body>
<div>
<p> text<note n="1"/>texttext<note n="2"/>text </p>
<p> text<note n="3"/>text </p>
</div>
<div>
text<note n="1"/>texttext<note n="2"/>text
</div>
</body>
Explanation: Appropriate use of the from attribute of xsl:number.
I have found following quick workaround:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalogp -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="div">
[div <xsl:apply-templates/>]
</xsl:template>
<xsl:template match="note">
[note n=<xsl:value-of select="count(preceding::note) - count(preceding::div//note) + 1"/>]
</xsl:template>
</xsl:stylesheet>
It works however only with "plain" div structure without a complex nesting.
You can test it here: http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog with your source xml.
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>adrock#gmail.com</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>ambientexpert#yahoo.co.uk</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>
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">adrock#gmail.com</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">ambientexpert#yahoo.co.uk</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>
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)