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 ....
The above transform, when applied to input document ...
... yields output document ...
Explanation
The
body
template uses the xsl:for-each-group to group the nd elements by common adjacenth2
(h2 headings). The xsl:for-each-group sequence constructor invokes thend
template to process eachnd
element in order, passing to it the group number, and whether or not thisnd
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.