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)
Related
I'm iterating through a node group using the following:
<xsl:for-each select="NewDataSet/VehicleDetail/Options/Option">
<xsl:choose>
<xsl:when test="string-length(.) > 40">
<div class="large">
<xsl:value-of select="."/>
</div>
</xsl:when>
<xsl:otherwise>
<div class="small">
<xsl:value-of select="."/>
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
What I would like to be able to do is group the large items (40 chars +) and the small items (40 chars and less) something like this:
<div class="largeItems">
<div class="large">Large Item</div>
<div class="large">Large Item</div>
<div class="large">Large Item</div>
<div class="large">Large Item</div>
<div class="large">Large Item</div>
</div>
<div class="smallItems">
<div class="small">Small Item</div>
<div class="small">Small Item</div>
<div class="small">Small Item</div>
<div class="small">Small Item</div>
<div class="small">Small Item</div>
</div>
Thanks.
Try:
<div class="largeItems">
<xsl:for-each select="NewDataSet/VehicleDetail/Options/Option[string-length() > 40]">
<div class="large">
<xsl:value-of select="."/>
</div>
</xsl:for-each>
</div>
<div class="smallItems">
<xsl:for-each select="NewDataSet/VehicleDetail/Options/Option[string-length() <= 40]">
<div class="small">
<xsl:value-of select="."/>
</div>
</xsl:for-each>
</div>
Or, if you prefer less code duplication:
<div class="largeItems">
<xsl:apply-templates select="NewDataSet/VehicleDetail/Options/Option[string-length() > 40]">
<xsl:with-param name="class" select="'large'"/>
</xsl:apply-templates>
</div>
<div class="smallItems">
<xsl:apply-templates select="NewDataSet/VehicleDetail/Options/Option[string-length() > 40]">
<xsl:with-param name="class" select="'small'"/>
</xsl:apply-templates>
</div>
and then:
<xsl:template match="Option">
<xsl:param name="class"/>
<div class="{$class}">
<xsl:value-of select="."/>
</div>
</xsl:template>
Untested because neither input nor context have been provided.
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>
I've the below XML.
Case 1
<body>
<nd>
<pnn>1.1</pnn>
<h1>PART 54</h1>
<ti>Construction</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>I INTRODUCT</h2>
<ti>Time</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>I INTRODUCT</h2>
<ti>Power</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>II APPLICATIONS</h2>
<ti>Filing</ti>
</nd>
</body>
Case 2
<body>
<nd>
<pnn>1.1</pnn>
<h1>PART 54</h1>
<h2>I INTRODUCT</h2>
<ti>Construction</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>I INTRODUCT</h2>
<ti>Time</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>II APPLICATIONS</h2>
<ti>Filing</ti>
</nd>
</body>
and the below XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<hmtl>
<head>
<title>New Version!</title>
</head>
<xsl:apply-templates select="body"></xsl:apply-templates>
</hmtl>
</xsl:template>
<xsl:template match="body">
<xsl:for-each select="nd">
<xsl:apply-templates select = "."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="pnn"/>
<xsl:template match="h1"/>
<xsl:template match="h2"/>
<xsl:template match="ti"/>
<xsl:variable name="FinalChap">
<xsl:value-of select="substring-before((//pnn)[1],'.')"/>
</xsl:variable>
<xsl:variable name="FinalChn">
<xsl:value-of select="$FinalChap"/>
</xsl:variable>
<xsl:variable name="Finalchapternumber">
<xsl:value-of select="format-number($FinalChn,'00')"/>
</xsl:variable>
<xsl:template name="section" match="nd">
<xsl:variable name="count">
<xsl:number count="nd" level="any"/>
</xsl:variable>
<xsl:variable name="classname">
<!--Get name attribute of current node -->
<xsl:value-of select="concat('section-sect','1')"/>
</xsl:variable>
<xsl:variable name="classname1">
<!--Get name attribute of current node -->
<xsl:value-of select="concat('section-sect','2')"/>
</xsl:variable>
<xsl:variable name="classname2">
<!--Get name attribute of current node -->
<xsl:value-of select="concat('section-sect','3')"/>
</xsl:variable>
<!--Create a string variable by concat string method -->
<xsl:variable name="sectionname">
<xsl:value-of select="concat('CH_',$Finalchapternumber,'-SEC-', $count)"/>
</xsl:variable>
<div class="{$classname}">
<xsl:if test="./h2 and not(preceding::h2[1]/text() = ./h2/text())">
<a name="{$sectionname}"> </a>
<div class="section-title">
<xsl:if test="not(preceding::h2[1]/text() = ./h2/text())">
<xsl:apply-templates select="h2" mode="section"/>
</xsl:if>
</div>
</xsl:if>
<xsl:if test="not(lower-case(./ti/text()) = lower-case(./h2/text()))">
<xsl:if test="./ti">
<div class="{$classname2}">
<xsl:apply-templates select="ti" mode="section"/>
</div>
</xsl:if>
</xsl:if>
<xsl:apply-templates select="child::node()[not(self::h2|self::ti)]"/>
</div>
</xsl:template>
<xsl:template match="ti" mode="section">
<xsl:apply-templates select="./node()[1][self::page]" mode="first"/>
<xsl:variable name="sectionnum">
<xsl:number count="nd" level="any"/>
</xsl:variable>
<a name="CH_{$Finalchapternumber}-SEC-{$sectionnum}"/>
<div class="section-title">
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="h2" mode="section">
<div class="section-title">
<xsl:apply-templates select="child::node()[not(self::fnt)]"/>
</div>
</xsl:template>
</xsl:transform>
here I'm trying to increment the section number based on a condition. The count should be done, if there is no node(here h2) <a name="CH_01-SEC-XX"></a> should be ignored I'm able to do it using <xsl:if test="./h2 and not(preceding::h2[1]/text() = ./h2/text())">, but the challenge i'm facing is count is not ignoring it.
Current output. Case 1
<div class="section-sect1">
<a name="CH_01-SEC-1"/>
<div class="section-title">
<div class="section-title">I INTRODUCT</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-1"/>
<div class="section-title">Construction</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3">
<a name="CH_01-SEC-2"/>
<div class="section-title">Time</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3">
<a name="CH_01-SEC-3"/>
<div class="section-title">Power</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_01-SEC-4"/>
<div class="section-title">
<div class="section-title">II APPLICATIONS</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-4"/>
<div class="section-title">Filing</div>
</div>
</div>
Expected output Case 1
<div class="section-sect1">
<a name="CH_01-SEC-1"/>
<div class="section-title">
<div class="section-title">I INTRODUCT</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-2"/>
<div class="section-title">Construction</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3">
<a name="CH_01-SEC-3"/>
<div class="section-title">Time</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3">
<a name="CH_01-SEC-4"/>
<div class="section-title">Power</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_01-SEC-5"/>
<div class="section-title">
<div class="section-title">II APPLICATIONS</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-6"/>
<div class="section-title">Filing</div>
</div>
</div>
Current Output Case 2
<div class="section-sect1"><a name="CH_01-SEC-1"></a><div class="section-title">
<div class="section-title">I INTRODUCT</div>
</div>
<div class="section-sect3"><a name="CH_01-SEC-1"></a><div class="section-title">Construction</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3"><a name="CH_01-SEC-2"></a><div class="section-title">Time</div>
</div>
</div>
<div class="section-sect1"><a name="CH_01-SEC-3"></a><div class="section-title">
<div class="section-title">II APPLICATIONS</div>
</div>
<div class="section-sect3"><a name="CH_01-SEC-3"></a><div class="section-title">Filing</div>
</div>
</div>
Expected output Case 2
<div class="section-sect1">
<a name="CH_01-SEC-1"/>
<div class="section-title">
<div class="section-title">I INTRODUCT</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-2"/>
<div class="section-title">Construction</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3">
<a name="CH_01-SEC-3"/>
<div class="section-title">Time</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_01-SEC-4"/>
<div class="section-title">
<div class="section-title">II APPLICATIONS</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-5"/>
<div class="section-title">Filing</div>
</div>
</div>
in current output there is duplicate CH_01-SEC-1 Can someone please let me know how to make it into a series of 1...n
Here is a working DEmo
Thanks
How about ....
<xsl:transform
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.0">
<xsl:output method="html" doctype-public="XSLT-compat" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:variable name="FinalChap">
<xsl:value-of select="format-number( xs:integer( substring-before((/body/nd/pnn)[1],'.')), '00')"/>
</xsl:variable>
<xsl:template match="/">
<html>
<head><title>New Version from Sean!</title></head>
<xsl:apply-templates />
</html>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="text()|processing-instruction()|comment()|#*" />
<xsl:template match="body">
<xsl:for-each-group select="nd" group-adjacent="h2/text()">
<xsl:variable name="group-position" select="position()" />
<xsl:for-each select="current-group()">
<xsl:call-template name="nd">
<xsl:with-param name="group-position" select="$group-position" />
<xsl:with-param name="is-head" select="position() eq 1" as="xs:boolean" />
</xsl:call-template>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
<xsl:template name="nd">
<xsl:param name="group-position" select="1" as="xs:integer" />
<xsl:param name="is-head" select="true()" as="xs:boolean" />
<div class="section-sect1">
<xsl:if test="$is-head">
<xsl:call-template name="a-link">
<xsl:with-param name="group-position" select="$group-position" />
<xsl:with-param name="delta" select="0" as="xs:integer" />
</xsl:call-template>
<div class="section-title">
<div class="section-title"><xsl:value-of select="h2" /></div>
</div>
</xsl:if>
<div class="section-sect3">
<xsl:call-template name="a-link">
<xsl:with-param name="group-position" select="$group-position" />
<xsl:with-param name="delta" select="1" as="xs:integer" />
</xsl:call-template>
<div class="section-title"><xsl:value-of select="ti" /></div>
</div>
</div>
</xsl:template>
<xsl:template name="a-link">
<xsl:param name="group-position" select="1" as="xs:integer" />
<xsl:param name="delta" select="0" as="xs:integer" />
<a name="CH_{$FinalChap}-SEC-{$group-position + count(preceding-sibling::nd) + $delta}" />
</xsl:template>
</xsl:transform>
The above transform, when applied to input document ...
<body>
<nd>
<pnn>1.1</pnn>
<h1>PART 54</h1>
<h2>I INTRODUCT</h2>
<ti>Construction</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>I INTRODUCT</h2>
<ti>Time</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>I INTRODUCT</h2>
<ti>Power</ti>
</nd>
<nd>
<h1>PART 54</h1>
<h2>II APPLICATIONS</h2>
<ti>Filing</ti>
</nd>
</body>
... yields output document ...
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>New Version from Sean!</title>
</head>
<div class="section-sect1">
<a name="CH_01-SEC-1"/>
<div class="section-title">
<div class="section-title">I INTRODUCT</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-2"/>
<div class="section-title">Construction</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3">
<a name="CH_01-SEC-3"/>
<div class="section-title">Time</div>
</div>
</div>
<div class="section-sect1">
<div class="section-sect3">
<a name="CH_01-SEC-4"/>
<div class="section-title">Power</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_01-SEC-5"/>
<div class="section-title">
<div class="section-title">II APPLICATIONS</div>
</div>
<div class="section-sect3">
<a name="CH_01-SEC-6"/>
<div class="section-title">Filing</div>
</div>
</div>
</html>
Explanation
The body template uses the xsl:for-each-group to group the nd elements by common adjacent h2 (h2 headings). The xsl:for-each-group sequence constructor invokes the nd template to process each nd element in order, passing to it the group number, and whether or not this nd is the first (the 'head') nd of the group.
I have inferred from your sample output, that the head nd of each group produces extra content being about the group, including an extra a-link.
The number of the a-link (for example 4 in CH_01-SEC-4) is equal to the count of preceding nd's, plus the group number, plus an extra 1 if we are not a head nd.
Alternative solutions
Just as there are many ways to skin a cat, there a quiet a few alternative solutions which would be equally valid. Instead of grouping, you could use a full push design. The extra content for head nodes (<div class="section-title">) could be achieved using a predicate on the template pattern, comparing this h2 with the previous h2. And the correcting number of the a-links could be achieved by micro-pipelining.
I've the below XML.
<?xml version="1.0" encoding="UTF-8"?>
<uaeccc>
<nd>
<AN>-2-0001</AN>
<h2>Ttle2</h2>
</nd>
<nd>
<h1>Ttle1</h1>
<h2>Ttle2</h2>
<h3>Part 1 Contracts</h3>
<h4>par2 sub contractts</h4>
</nd>
<nd>
<h1>Ttle1</h1>
<h2>Ttle2 </h2>
<h3>Part 1 Contracts</h3>
<h4>Part 2 Sub contracts</h4>
</nd>
<nd>
<h1>Ttle1</h1>
<h2>Ttle2 </h2>
<h3>Part 1 Contracts</h3>
<h4>part 2 sub contracts</h4>
</nd>
</uaeccc>
Here i was trying to increment a number, but it is getting incremented only in that section.
Below is my XSLT.
<xsl:template match="uaeccc">
<xsl:for-each select="nd">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template name="section" match="nd">
<xsl:apply-templates select="./node()[1][self::page]" mode="first"/>
<!-- Variables-->
<xsl:variable name="getChap">
<xsl:value-of select="substring-before(substring-after((//AN)[1],'-'),'-')"/>
</xsl:variable>
<xsl:variable name="count">
<xsl:number level="any"/>
</xsl:variable>
<xsl:variable name="classname">
<!--Get name attribute of current node -->
<xsl:value-of select="concat('section-sect','1')"/>
</xsl:variable>
<xsl:variable name="Chn">
<xsl:value-of select="format-number($getChap,'00')"/>
</xsl:variable>
<xsl:variable name="chapternumber">
<xsl:value-of select="$Chn"/>
</xsl:variable>
<xsl:variable name="sectnum">
<xsl:number level="any" count="section" format="1"/>
</xsl:variable>
<!--Create a string variable by concat string method -->
<xsl:variable name="sectionname">
<xsl:value-of select="concat('CH_',$chapternumber,'-SEC-', $count)"/>
</xsl:variable>
<!-- Template Content -->
<div class="{$classname}">
<a name="{$sectionname}"> </a>
<div class="section-title">
<xsl:apply-templates select="h3"/>
</div>
<xsl:if test="./h4">
<div class="{$classname}">
<a name="{$sectionname}"> </a>
<div class="section-title2">
<xsl:apply-templates select="h4"/>
</div>
</div>
</xsl:if>
<xsl:apply-templates select="child::node()[not(self::h4| self::h3)]"/>
</div>
</xsl:template>
<xsl:template match="AN"/>
<xsl:template match="h1"/>
<xsl:template match="h2"/>
My current output is
<div class="section-sect1">
<a name="CH_02-SEC-1"></a>
<div class="section-title"></div>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-2"></a>
<div class="section-title">
<h3>Part 1 Contracts</h3>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-2"></a>
<div class="section-title2">
<h4>par2 sub contractts</h4>
</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-3"></a>
<div class="section-title">
<h3>Part 1 Contracts</h3>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-3"></a>
<div class="section-title2">
<h4>Part 2 Sub contracts</h4>
</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-4"></a>
<div class="section-title">
<h3>Part 1 Contracts</h3>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-4"></a>
<div class="section-title2">
<h4>part 2 sub contracts</h4>
</div>
</div>
</div>
and expected output is
<div class="section-sect1">
<a name="CH_02-SEC-1"></a>
<div class="section-title"></div>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-2"></a>
<div class="section-title">
<h3>Part 1 Contracts</h3>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-3"></a>
<div class="section-title2">
<h4>par2 sub contractts</h4>
</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-4"></a>
<div class="section-title">
<h3>Part 1 Contracts</h3>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-5"></a>
<div class="section-title2">
<h4>Part 2 Sub contracts</h4>
</div>
</div>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-6"></a>
<div class="section-title">
<h3>Part 1 Contracts</h3>
</div>
<div class="section-sect1">
<a name="CH_02-SEC-7"></a>
<div class="section-title2">
<h4>part 2 sub contracts</h4>
</div>
</div>
</div>
Here i want to increment the number after SEC- every time there is $classnamecalled.But here in my XSLT, the increment occurs but is same in case of subsection also.
please let me know how can i get it fixed.
Here is a Working Demo
I can't make heads or tails of your code. FWIW, the following stylesheet, when applied to your example input, will produce the required output (with the exception of wrapping the result in a single root element):
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="*"/>
<xsl:template match="/uaeccc">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="nd">
<div class="section-sect1">
<xsl:variable name="sectionnum">
<xsl:number count="nd|h4" level="any"/>
</xsl:variable>
<a name="CH_02-SEC-{$sectionnum}"/>
<div class="section-title">
<xsl:copy-of select="h3"/>
</div>
<xsl:apply-templates select="h4"/>
</div>
</xsl:template>
<xsl:template match="h4">
<div class="section-sect1">
<xsl:variable name="sectionnum">
<xsl:number count="nd|h4" level="any"/>
</xsl:variable>
<a name="CH_02-SEC-{$sectionnum}"/>
<div class="section-title2">
<xsl:copy-of select="."/>
</div>
</div>
</xsl:template>
</xsl:stylesheet>
I am trying to create a nav menu in Composite C1 for the Bootstrap framework, but I am unsure how to get submenus to show up in the menu. Here is what I have
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:in="http://www.composite.net/ns/transformation/input/1.0"
xmlns:lang="http://www.composite.net/ns/localization/1.0"
xmlns:f="http://www.composite.net/ns/function/1.0"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="xsl in lang f">
<xsl:param name="sitemap" select="/in:inputs/in:result[#name='SitemapXml']/Page" />
<xsl:template match="/">
<html>
<head>
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<xsl:for-each select="$sitemap[#isopen='true']">
<li>
<a href="{#URL}">
<xsl:if test="#iscurrent='true'" >
<xsl:attribute name="class">active</xsl:attribute>
</xsl:if>
<xsl:value-of select="#MenuTitle" />
</a>
</li>
<xsl:apply-templates select="Page" />
</xsl:for-each>
</ul>
</div>
</div>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="Page">
<xsl:if test="count(#MenuTitle)">
<li>
<a href="{#URL}">
<xsl:if test="#isopen='true'" >
<xsl:attribute name="class">active</xsl:attribute>
</xsl:if>
<xsl:value-of select="#MenuTitle" />
</a>
</li>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
I am unsure what I need to add to get the sub-menus. Suggestions?
Try out something like this
<xsl:template match="/">
<html>
<head>
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<xsl:for-each select="$sitemap[#isopen='true']">
<li>
<xsl:if test="#iscurrent='true'" >
<xsl:attribute name="class">active</xsl:attribute>
</xsl:if>
<a href="{#URL}">
<xsl:value-of select="#MenuTitle" />
</a>
</li>
<xsl:apply-templates select="Page" />
</xsl:for-each>
</ul>
</div>
</div>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="Page">
<xsl:variable name="depth" select="#Depth" />
<xsl:variable name="isDropDown" select="count(./*) > 0 and $depth < 3" />
<xsl:if test="count(#MenuTitle)">
<li>
<xsl:if test="#isopen='true'" >
<xsl:attribute name="class">active</xsl:attribute>
</xsl:if>
<xsl:if test="$isDropDown" >
<xsl:attribute name="class">dropdown</xsl:attribute>
</xsl:if>
<a href="{#URL}">
<xsl:if test="$isDropDown" >
<xsl:attribute name="class">dropdown-toggle</xsl:attribute>
</xsl:if>
<xsl:if test="$isDropDown" >
<xsl:attribute name="data-toggle">dropdown</xsl:attribute>
</xsl:if>
<xsl:value-of select="#MenuTitle" />
<xsl:if test="$isDropDown" >
<b class="caret"></b>
</xsl:if>
</a>
<xsl:if test="$isDropDown">
<ul class="dropdown-menu">
<xsl:apply-templates select="./*" />
</ul>
</xsl:if>
</li>
</xsl:if>