counter in xslt not working correctly - xslt
i'm having the below XML Document.
<?xml version="1.0" encoding="UTF-8"?>
<chapter num="A">
<title>
<content-style font-style="bold">PART 1 GENERAL PRINCIPLES</content-style>
</title>
<section level="sect1">
<title>
<content-style font-style="bold">Chapter 2: PREVENTING COMMERCIAL DISPUTES</content-style>
</title>
<section level="sect2" number-type="manual" num="1.">
<title>INTRODUCTION</title>
<para>
<phrase>2.001</phrase> With increasing competition in the business environment and the need to provide value for money to customers, most, if not all businesses, cannot afford to continuously be engaged in the dispute resolution arena as though it were a part of their core business. If all the disputes of a business entity have to be litigated or arbitrated to the bitter end, then this will become a substantial drain on its financial resources and big distraction for its management. Prolonged engagement in litigation and arbitration will undoubtedly have a detrimental effect on the business.</para>
<para>
<phrase>2.002</phrase> Preventing or minimising disputes requires businesses to know and understand the people they are dealing with and they will also need to ensure that the governing contracts are clearly and carefully drafted in order to safeguard the rights of both parties. The parties need to devote resources to train their employees to carefully and skilfully monitor the performance of the contracts and to maintain proper and adequate documentary records. This requires financial investment which some businesses are unable or reluctant to budget for. However, those businesses which have a keen awareness of the need to prevent or minimise disputes and are willing to provide the financial investment to attain this will find that, with a manageable preventative dispute resolution philosophy in place, this will, in the long term, be cost-effective and above all, create an environment that preserves close working relationships.</para>
</section>
<section level="sect2" number-type="manual" num="2.">
<title>SELECTING A COUNTERPARTY</title>
<para>
<phrase>2.003</phrase> Commercial disputes inevitably arise between two or more parties under a commercial contract. The attributes of the counterparty with which one contracts will therefore have an impact on whether disputes can be prevented or, even if not, whether disputes can be resolved in an efficient and cost-effective manner, which will ultimately benefit both parties.</para>
<para>
<phrase>2.004</phrase> Consideration should be given to certain aspects of the counterparty before a contract is entered into. These attributes of a contracting party can impact on whether the relationship is likely to go smoothly or whether it is going to be “dispute prone”.</para>
<section level="sect2" number-type="manual" num="(a)">
<title>Financial power</title>
<para>
<phrase>2.005</phrase> A contracting party which has financial substance is, in general, more likely to be willing to abide by their contractual obligations, simply because they are relatively easy targets of a lawsuit. On the other hand, where one contracts with an insubstantial or “fly-by-night” party, there is a genuine concern that, once the contract becomes unprofitable or if something goes wrong, there is a bigger propensity for disputes to arise as a result of the latter seeking to avoid its obligations.</para>
</section>
<section level="sect2" number-type="manual" num="(b)">
<title>Market reputation</title>
<para>
<phrase>2.006</phrase> A contracting party which has a market reputation it wishes to safeguard is likely to be more careful in the type of disputes it would be likely to get involved in. Listed companies or those which have a public image to preserve are, in general, more likely to avoid litigating every claim irrespective of size (unless such claims, if not litigated, are liable to open up floodgates) to minimise the bad publicity associated with being in the courts too often, or giving the impression to potential future contracting parties that they are litigious and difficult to deal with.</para>
</section>
<section level="sect2" number-type="manual" num="(c)">
<title>Location and culture</title>
<para>
<phrase>2.007</phrase> This is a sensitive topic and therefore there will be no specific references. However, a discussion of this type would be incomplete without acknowledging the fact that businesses or projects in certain parts of the world are more prone to conflicts or natural disasters and are more likely to end up in disputes than those in more “peaceful” parts of the world. Certain cultures tend also to be more litigious than others, and when contracting with parties of certain cultural backgrounds that focus less on mutual tolerance and co-operation, there will be more expectation of disputes.</para>
</section>
<section level="sect2" number-type="manual" num="(d)">
<title>Focus/investment on risk prevention</title>
<para>
<phrase>2.008</phrase> Certain contracting parties, more often seen in developed countries, have a better awareness of the law and the need to invest in risk prevention in order to minimise the probability of disputes. “Investments” in this regard include spending money to vet their business partners, including investigating their financial status and their market reputation, and allowing their legal department a sufficient budget to properly review draft contracts, assist with negotiations and to keep fully up-to-date with the latest legal developments.</para>
</section>
</section>
<section level="sect2" number-type="manual" num="3.">
<title>CONTRACT NEGOTIATION AND DRAFTING</title>
<para>
<phrase>2.009</phrase> There are two basic ways in which conflicts can be avoided without the need for the use of dispute resolution mechanisms. The first is the use of negotiation skills to negotiate a contract that affords the best terms and conditions possible, covering all or most foreseeable contingencies. Having clear and favourable provisions in a contract puts a party in a better position, especially when it is sought to resolve disputes at their source, without the need to revert to the dispute resolution mechanisms provided for in the contract. This, without a doubt, is the cheapest and most effective means of avoiding disputes or resolving possible disputes. The importance of contract negotiations should not be lightly dismissed.</para>
<para>
<phrase>2.010</phrase> The second is having a clearly drafted contract that is well thought out and planned and serves everyone’s interests. Often a hastily drafted contract that is put together at the last minute results in uncertainty and vagueness of terms which could potentially create disputes. The inclusion of appropriate clauses (for example, clauses that cover force majeure or hardship) provide for changing conditions that may render the contract impossible to perform are of major importance. The drafting of such clauses is relatively technical in nature and requires the skills of a competent drafter of commercial contracts to ensure that they are manageable from a commercial standpoint.</para>
<para>
<phrase>2.011</phrase> An area to be aware of is the use of standard form contracts and adopting such forms within the existing framework of the contract. Although there are a variety of such standard form contracts available in the market place to be referred to, care must be taken, as these forms are only a guide to assist in the drafting of a contract that suits individual needs. Consulting legal counsel for advice is beneficial, especially when the contract touches on issues such as jurisdiction, which can often be difficult concepts for a lay person to understand.</para>
<para>
<phrase>2.012</phrase> The drafting of specialist contracts such as those in the construction, insurance, commodity and maritime fields requires a great deal of industry knowledge and experience to ensure that suitable wording is used to minimise the chances of disputes. However, regardless of the type of contract involved, there are certain provisions which are generic in nature, and the inclusion of which will generally (although not always) minimise the scope of the disputes between the parties, and are usually good to have. These provisions are often referred to as boilerplate clauses.</para>
<para>
<phrase>2.013</phrase> The importance of boilerplate clauses is often overlooked as the parties tend to focus on the commercial terms of the contract, such as the cost of the goods or services being provided. Failure to include appropriate boilerplate clauses may prevent a party from effectively enforcing its rights under the contract and offer an escape route to the defaulting party from its liabilities.</para>
</section>
</section>
</chapter>
and when i apply the below xslt, the counter in section (taken as ), everytime a new section with number in num is found, the counter is getting reset to 1 but if the num is having value like (a),(b) .. it is continuing, what i want is, the counter should be never be reset to 1. please help me in acheiving this.
XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ntw="Number2Word.uri" exclude-result-prefixes="ntw">
<xsl:variable name="ThisDocument" select="document('')"/>
<xsl:output method="html"/>
<xsl:template match="/">
<xsl:text disable-output-escaping="yes"><!DOCTYPE></xsl:text>
<html>
<head>
<xsl:text disable-output-escaping="yes"><![CDATA[</meta>]]></xsl:text>
<title>
<xsl:value-of select="substring-after(chapter/section/title,':')"/>
</title>
<link rel="stylesheet" href="er:#css" type="text/css"/><xsl:text disable-output-escaping="yes"><![CDATA[</link>]]></xsl:text>
</head>
<body>
<xsl:apply-templates/>
<section class="tr_footnotes">
<hr/>
<xsl:apply-templates select="//footnote" mode="footnote"/>
</section>
</body>
</html>
</xsl:template>
<xsl:template match="chapter">
<section class="tr_chapter">
<div class="chapter">
<xsl:variable name="l">
<xsl:value-of select="substring(substring-after(section/title,' '),1,1)"/>
</xsl:variable>
<a name="AHK_CH_0{$l}"/>
<div class="chapter-title">
<xsl:variable name="titl">
<xsl:value-of select="substring-after(section/title,':')"/>
</xsl:variable>
<span class="chapter-num">
<xsl:value-of select="concat('Chapter ',$l,' ')"/>
</span>
<xsl:value-of select="$titl"/>
</div>
<div class="para align-center">
<span class="font-style-italic">
<xsl:value-of select="document('AHK-authors.xml')/chapters/chapter[#no=$l]"/>
</span>
</div>
<div class="para align-right"><span class="format-smallcaps">Para</span>.</div>
<div class="toc">
<div class="toc-part">
<table class="toc-div">
<tbody>
<tr>
<td>
<xsl:for-each select="current()/section/section|current()/section/section/section[contains(#num, '(')]|current()/section/section/section/section[contains(#num, '(')]">
<xsl:call-template name="IndexItem">
</xsl:call-template>
</xsl:for-each>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<xsl:apply-templates select="section/section"/>
</div>
</section>
</xsl:template>
<xsl:template match="chapter/para">
<div class="para align-right">
<span class="format-smallcaps">Para</span>.
</div>
<xsl:apply-templates select="section"/>
</xsl:template>
<xsl:template name="fig" match="figure">
<div class="figure">
<div class="figure-title">
<xsl:value-of select="current()/title"/>
</div>
<xsl:variable name="numb">
<xsl:value-of select="substring-after(graphic/#href,'_')"/>
</xsl:variable>
<xsl:variable name="figCon">
<xsl:value-of select="concat('er:#page-',$numb)"/>
</xsl:variable>
<img class="graphic" src="{$figCon}" alt=""/>
</div>
</xsl:template>
<xsl:template name="IndexItem">
<xsl:if test="not(contains(#level,'sect1'))"><!--changed fron #num to sect2-->
<xsl:variable name="tocpg">
<xsl:value-of select="concat('#P',descendant::para/phrase[1]/text())"/>
</xsl:variable>
<xsl:variable name="tocpgtag" select="translate($tocpg,'.', '-')"/>
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="text" select="current()/title/text()"/>
<xsl:variable name="Brac">
<xsl:choose>
<xsl:when test="contains(current()/#num,'(')">
<xsl:value-of select="2"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="d">
<xsl:value-of select="concat('toc-item-',$ThisDocument//ntw:nums[#num=$Brac]/#word,'-level')"/>
</xsl:variable>
<table class="{$d}">
<tbody>
<tr>
<td class="toc-item-num">
<xsl:value-of select="#num"/>
</td>
<td class="toc-title">
<xsl:value-of select="concat(substring($text,1,1), translate(substring($text,2), $uppercase, $smallcase))"/>
</td>
<td class="toc-pg">
<a href="{$tocpgtag}">
<xsl:value-of select="descendant::para/phrase[1]/text()"/>
</a>
</td>
</tr>
</tbody>
</table>
</xsl:if>
</xsl:template>
<!-- Index Templates Complete -->
<!-- Paragraph templates -->
<xsl:template name="section" match="section">
<!-- Variables-->
<xsl:variable name="classname">
<!--Get name attribute of current node -->
<xsl:value-of select="concat('section-',parent::section/#level)"/>
</xsl:variable>
<xsl:variable name="chapternumber">
<!-- Get num attribute of parent node -->
<xsl:variable name="StrL">
<xsl:value-of select="string-length(substring(substring-after(ancestor::chapter/section/title,'Chapter '),1,1))"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$StrL>1">
<xsl:value-of select="substring(substring-after(ancestor::chapter/section/title,'Chapter '),1,1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('0',substring(substring-after(ancestor::chapter/section/title,'Chapter '),1,1))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="sectnum">
<xsl:number format="1"/>
</xsl:variable>
<!--Create a string variable by concat string method -->
<xsl:variable name="sectionname">
<xsl:value-of select="concat('CH_',$chapternumber,'-SEC-', $sectnum)"/>
</xsl:variable>
<!-- Template Content -->
<div class="{$classname}">
<a name="{$sectionname}"> </a>
<div class="section-title">
<span class="section-num">
<xsl:value-of select="#num"/>
<xsl:text> </xsl:text>
</span>
<xsl:apply-templates select="title"/>
</div>
<xsl:apply-templates select="child::node()[not(self::title)]"/>
</div>
</xsl:template>
<xsl:template name="para" match="section/para">
<div class="para">
<xsl:apply-templates select="phrase"/>
<span class="phrase">
<xsl:value-of select="current()/phrase"/>
</span>
<xsl:choose>
<xsl:when test="contains(current()/text(),'Chapter')">
<xsl:variable name="x">
<xsl:value-of select="substring(substring-before(current()/text(),'Chapter'),1)"/>
</xsl:variable>
<xsl:variable name="y">
<xsl:value-of select="substring(substring-after(current()/text(),'Chapter'),4)"/>
</xsl:variable>
<xsl:variable name="z">
<xsl:value-of select="normalize-space(substring-before(substring-after(current()/text(),'Chapter'),'.'))"/>
</xsl:variable>
<xsl:variable name="h">
<xsl:value-of select="string-length($z)"/>
</xsl:variable>
<xsl:value-of select="$x"/>
<xsl:choose>
<xsl:when test="$h =1">
<a href="{concat('er:#AHK_CH_0',$z,'/AHK_CH_0',$z)}">
<xsl:value-of select="concat('Chapter',$z)"/>
</a>
</xsl:when>
<xsl:otherwise>
<a href="{concat('er:#AHK_CH_',$z,'/AHK_CH_',$z)}">
<xsl:value-of select="concat('Chapter',$z)"/>
</a>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="$y "/>
<xsl:apply-templates select="footnote"/>
<xsl:apply-templates select="current()/phrase/text()"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="child::node()[not(self::phrase)]"/>
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:template>
<xsl:template name="phrase" match="phrase">
<xsl:variable name="phrase">
<xsl:value-of select="concat('P',text())"/>
</xsl:variable>
<xsl:variable name="newphrase" select="translate($phrase,'.','-')"/>
<a>
<xsl:attribute name="name"><xsl:value-of select="$newphrase"></xsl:value-of></xsl:attribute>
</a>
</xsl:template>
<!-- Table Templates -->
<xsl:template name="table" match="table">
<table style="frame-{current()/#frame} width-{translate(current()/#width,'%','')}">
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template match="tgroup">
<colgroup>
<xsl:apply-templates select=".//colspec"/>
</colgroup>
<xsl:apply-templates select="child::node()[not(self::colspec)]"/>
</xsl:template>
<xsl:template name="tbody" match="tgroup/tbody">
<tbody>
<xsl:for-each select="current()/row">
<xsl:call-template name="row"/>
</xsl:for-each>
</tbody>
</xsl:template>
<xsl:template name="thead" match="tgroup/thead">
<xsl:for-each select="current()/row"><thead>
<tr>
<xsl:for-each select="current()/entry">
<xsl:call-template name="headentry"/>
</xsl:for-each>
</tr>
</thead>
</xsl:for-each>
</xsl:template>
<xsl:template name="colspec" match="colspec">
<col class="colnum-{current()/#colnum} colname-{current()/#colname} colwidth-{translate(current()/#colwidth,'%','')}"/>
</xsl:template>
<xsl:template name="row" match="tbody/row">
<tr>
<xsl:for-each select="current()/entry">
<xsl:call-template name="entry"/>
</xsl:for-each>
</tr>
</xsl:template>
<xsl:template name="entry" match="entry">
<xsl:variable name="count">
<xsl:value-of select="count(preceding-sibling::* | following-sibling::*)"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$count < 2">
<xsl:if test="position()=1">
<td>
<div class="para align-center">
<xsl:value-of select="para[position()=1]"/>
</div>
</td>
<td>
<div class="para">
<xsl:value-of select="following-sibling::node()"/>
</div>
</td>
</xsl:if>
</xsl:when>
<xsl:when test="$count > 1">
<td>
<div class="para">
<xsl:apply-templates/>
</div>
</td>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="headentry">
<th>
<xsl:if test="translate(current()/#namest,'col','') != translate(current()/#nameend,'col','')">
<xsl:variable name="colspan">
<xsl:value-of select="translate(current()/#nameend,'col','') - translate(current()/#namest,'col','') + 1"/>
</xsl:variable>
<xsl:attribute name="colspan"><xsl:value-of select="$colspan"></xsl:value-of></xsl:attribute>
</xsl:if>
<div class="para">
<xsl:value-of select="current()/para/text()"/>
<xsl:apply-templates/>
</div>
</th>
</xsl:template>
<!-- Table Templates complete -->
<!--List templates -->
<xsl:template name="orderedlist" match="orderedlist">
<ol class="eng-orderedlist orderedlist">
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template name="orderitem" match="item">
<li class="item">
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template name="orderitempara" match="item/para">
<div class="para">
<span class="item-num">
<xsl:if test="position()=1">
<xsl:value-of select="parent::item[1]/#num"/>
<xsl:text> </xsl:text>
</xsl:if>
</span>
<xsl:apply-templates/>
</div>
</xsl:template>
<!--List templates Complete -->
<!-- Paragraph templates Complete -->
<!-- Footnote Templates-->
<xsl:template match="footnote">
<sup>
<a>
<xsl:attribute name="name"><xsl:text>f</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="href"><xsl:text>#ftn.</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="class"><xsl:text>tr_ftn</xsl:text></xsl:attribute>
<xsl:number level="any" count="footnote" format="1"/>
</a>
</sup>
</xsl:template>
<xsl:template match="footnote" mode="footnote">
<div class="tr_footnote">
<div class="footnote">
<sup>
<a>
<xsl:attribute name="name"><xsl:text>ftn.</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="href"><xsl:text>#f</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="class"><xsl:text>tr_ftn</xsl:text></xsl:attribute>
<xsl:number level="any" count="footnote" format="1"/>
</a>
</sup>
<div class="a">
<xsl:variable name="new">
<xsl:value-of select="current()"/>
</xsl:variable>
<xsl:variable name="new1">
<xsl:value-of select="substring(substring-after(current(),'paragraph'),2,5)"/>
</xsl:variable>
<xsl:variable name="roo">
<xsl:value-of select="substring(//#num,2)"/>
</xsl:variable>
<xsl:variable name="befTex">
<xsl:value-of select="substring-before(current(),'paragraph')"/>
</xsl:variable>
<xsl:variable name="before">
<xsl:value-of select="substring-before($new1,'.')"/>
</xsl:variable>
<xsl:variable name="after">
<xsl:value-of select="substring(substring-after($new1,'.'),1,3)"/>
</xsl:variable>
<xsl:variable name="centTex">
<xsl:value-of select="substring(substring-after(current(),$after),1)"/>
</xsl:variable>
<xsl:variable name="pCon">
<xsl:value-of select="concat('paragraph',' ',$before,'.',$after)"/>
</xsl:variable>
<xsl:variable name="tes">
<xsl:if test="contains($centTex,'chapter')">
<xsl:value-of select="concat(' ',substring(substring-before($centTex,'chapter'),2))"/>
</xsl:if>
</xsl:variable>
<xsl:variable name="ChapNu">
<xsl:value-of select="normalize-space(substring(substring-after(current(),'chapter'),1,2))"/>
</xsl:variable>
<xsl:variable name="ChapNuC">
<xsl:value-of select="concat('er:#BVI_CH_0',$ChapNu,'/BVI_CH_0',$ChapNu)"/>
</xsl:variable>
<xsl:variable name="curSel">
<xsl:value-of select="concat('#P',$before,'-',$after)"/>
</xsl:variable>
<xsl:variable name="ChapCon">
<xsl:value-of select="concat('chapter',' ',substring(substring-after(current(),'chapter'),2,1))"/>
</xsl:variable>
<xsl:variable name="conc1">
<xsl:value-of select="concat('er:#BVI_CH_0',$before,'/P',$before,'-',$after)"/>
</xsl:variable>
<xsl:value-of select="$befTex"/>
<xsl:choose>
<xsl:when test="contains(substring(substring-after($new,'paragraph'),1,3),'.')">
<xsl:choose>
<xsl:when test="$before = $roo">
<a href="{$curSel}">
<xsl:value-of select="$pCon"/>
</a>
</xsl:when>
<xsl:otherwise>
<a href="{$conc1}">
<xsl:value-of select="$pCon"/>
</a>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="$tes"/>
<xsl:if test="contains($centTex,'chapter')">
<a href="{$ChapNuC}">
<xsl:value-of select="$ChapCon"/>
</a>
</xsl:if>
<xsl:text>.</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</div>
</div>
</div>
</xsl:template>
<xsl:template match="footnote/para/uri">
<xsl:variable name="url1">
<xsl:value-of select="translate(#href, '<','')" />
</xsl:variable>
<xsl:variable name="url2">
<xsl:value-of select="translate($url1, '>','')" />
</xsl:variable>
<a href="{$url2}">
<xsl:value-of select="." />
</a>
</xsl:template>
<!-- Footnote Templates Complete -->
<xsl:template match="content-style">
<xsl:choose>
<xsl:when test="#format='smallcaps'">
<xsl:value-of select="translate(normalize-space(.),'ABCDEFGHIJKLMNOPQRSTUVWXZ','abcdefghijklmnopqrstuvwxyz')"/>
</xsl:when>
<xsl:when test="#format='superscript'">
</xsl:when>
<xsl:otherwise>
<xsl:variable name="fontStyle">
<xsl:value-of select="concat('font-style-',#font-style)"/>
</xsl:variable>
<span class="{$fontStyle}">
<xsl:apply-templates/>
</span>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Namespace ntw-->
<ntw:nums num="1" word="first"/>
<ntw:nums num="2" word="second"/>
<ntw:nums num="3" word="third"/>
<ntw:nums num="4" word="forth"/>
<ntw:nums num="5" word="fifth"/>
<ntw:nums num="6" word="sixth"/>
<ntw:nums num="7" word="seventh"/>
<ntw:nums num="8" word="eighth"/>
<ntw:nums num="9" word="nighth"/>
<ntw:nums num="10" word="tenth"/>
<!-- Namespace ntw ends -->
</xsl:stylesheet>
Thanks
I've used the counter value as 1 in the below code, but i\ need to use the code given in the second block below.
<xsl:variable name="sectionname">
<xsl:value-of select="concat('CH_',$chapternumber,'-SEC-', $sectnum)"/>
</xsl:variable>
<xsl:variable name="sectnum">
<xsl:for-each select="Current()">
<xsl:value-of select="count(preceding-sibling::*)"/>
</xsl:for-each/>
</xsl:variable>
and this will give the value.
Related
How to implement attribute specific templates without redundancy
I'm familiar with using templates that key off attributes as follows (e.g. key off of the presence of foo): <xsl:template match="something[#foo]"> <xsl:template match="something[not(#foo)]"> However, if much of the content of these templates is the same, is there a better way that still uses templates, since the community appears to prefer them? Or is the solution to just use xsl:choose. It's clearly preferable not to write duplicate code that must be maintained in both templates. EDIT: Here's my specific set of templates: <xsl:template match="item[not(#format)]"> <td class="{current()/../#name}_col status_all_col"> <xsl:value-of select="current()"/> <xsl:value-of select="#units"/> </td> </xsl:template> <xsl:template match="item[#format]"> <td class="{current()/../#name}_col status_all_col"> <xsl:value-of select="format-number(current(), #format)"/> <xsl:value-of select="#units"/> </td> </xsl:template> and here's what I currently have using choose: <xsl:template match="item"> <td class="{current()/../#name}_col status_all_col"> <xsl:choose> <xsl:when test="#format"> <xsl:value-of select="format-number(current(), #format)"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="current()"/> </xsl:otherwise> </xsl:choose> <xsl:value-of select="#units"/> </td> </xsl:template>
I would definitely use xsl:choose in this situation. Just to demonstrate how you could use templates without code repetition: <xsl:template match="item"> <td class="{../#name}_col status_all_col"> <xsl:apply-templates select="." mode="format"/> <xsl:value-of select="#units"/> </td> </xsl:template> <xsl:template match="item[not(#format)]" mode="format"> <xsl:value-of select="."/> </xsl:template> <xsl:template match="item[#format]" mode="format"> <xsl:value-of select="format-number(., #format)"/> </xsl:template> But I fail to see what advantage this would have. On the contrary, it suffers from the GOTO syndrome. BTW, this may not be the best example, since I believe that supplying an empty string as the second argument of the format-number() function will result in the number being returned as-is. So you could just use a single template to match all: <xsl:template match="item"> <td class="{../#name}_col status_all_col"> <xsl:value-of select="format-number(current(), #format)"/> <xsl:value-of select="#units"/> </td> </xsl:template>
XSL, SUM & Multiply with Condition
Im doing an assignment for University (so im new to XSL coding) in making a quasi ecommerce site, and will provide as much detail as i can so it makes sense. Sample XML Data: <Items> <Item> <ItemID>50001</ItemID> <ItemName>Samsung Galaxy S4</ItemName> <ItemPrice>629</ItemPrice> <ItemQty>14</ItemQty> <ItemDesc>4G Mobile</ItemDesc> <QtyHold>0</QtyHold> <QtySold>1</QtySold> </Item> <Item> <ItemID>50002</ItemID> <ItemName>Samsung Galaxy S5</ItemName> <ItemPrice>779</ItemPrice> <ItemQty>21</ItemQty> <ItemDesc>4G Mobile</ItemDesc> <QtyHold>0</QtyHold> <QtySold>1</QtySold> </Item> </Items> Website So the process is, when a person clicks 'Add to Cart' in the top Table, the ItemQty is decreased by 1 on the ItemQty in the XML, while it increases by 1 in the QtyHold in the XML. (QtyHold represents what has been added to the shopping Cart. Thus if QtyHold is >0 then its been added to the Cart) My problem refers to the 2nd Table (code below), where the Total figure works - only if dealing with 1 Item. Thus, if Item Number '50001' is added a 2nd time, the Total wont change. <xsl:template match="/"> <fieldset> <legend>Shopping Cart</legend> <BR /> <table border="1" id="CartTable" align="center"> <tr><th>Item Number</th> <th>Price</th> <th>Quantity</th> <th>Remove</th></tr> <xsl:for-each select="/Items/Item[QtyHold > 0]"> <tr><td><xsl:value-of select="ItemID"/></td> <td>$<xsl:value-of select="ItemPrice"/></td> <td><xsl:value-of select="QtyHold"/></td> <td><button onclick="addtoCart({ItemID}, 'Remove')">Remove from Cart</button></td> </tr> </xsl:for-each> <tr><td ALIGN="center" COLSPAN="3">Total:</td><td>$<xsl:value-of select="sum(//Item[QtyHold >0]/ItemPrice)"/></td></tr> </table> <BR /> <button onclick="Purchase()" class="submit_btn float_l">Confirm Purchase</button> <button onclick="CancelOrder()" class="submit_btn float_r">Cancel Order</button> </fieldset> </xsl:template> </xsl:stylesheet> So what needs to happen is within the following code, while it checks if the QtyHold is greater than 0 (which would mean its in the shopping Cart) & to sum these values, it also needs to multiply QtyHold & ItemPrice. <xsl:value-of select="sum(//Item[QtyHold >0]/ItemPrice)"/> I tried many variations of Code like this below... but can't seem to make anything work. select="sum(//Item[QtyHold >0]/ItemPrice)/(QtyHold*ItemPrice"/>
If you are using XSLT 2.0, the expression you could use would be this: <xsl:value-of select="sum(//Item[QtyHold >0]/(ItemPrice * QtyHold))"/> However, in XSLT 1.0 that is not allowed. Instead, you could achieve the result you need with an extension function. In particular the "node-set" function. First you would create a variable like this, in which you construct new nodes holding each item total <xsl:variable name="itemTotals"> <xsl:for-each select="//Item[QtyHold >0]"> <total> <xsl:value-of select="ItemPrice * QtyHold" /> </total> </xsl:for-each> </xsl:variable> Ideally, you would like to do sum($itemTotals/total), but this won't work, because itemTotals is a "Result Tree Fragment" and the sum function only accepts a node-set. So you use the node-set extension function to convert it. First declare this namespace in your XSLT... xmlns:exsl="http://exslt.org/common" Then, your sum function would look like this: <xsl:value-of select="sum(exsl:node-set($itemTotals)/total)"/> Alternatively, if you couldn't even use an extension function, you could use the "following-sibling" approach, to select each Item at a time, and keep a running total. So, you would have a template like this: <xsl:template match="Item" mode="sum"> <xsl:param name="runningTotal" select="0" /> <xsl:variable name="newTotal" select="$runningTotal + ItemPrice * QtyHold" /> <xsl:variable name="nextItem" select="following-sibling::Item[1]" /> <xsl:choose> <xsl:when test="$nextItem"> <xsl:apply-templates select="$nextItem" mode="sum"> <xsl:with-param name="runningTotal" select="$newTotal" /> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:value-of select="$newTotal" /> </xsl:otherwise> </xsl:choose> </xsl:template> And to call it, to get the sum, you just start off by selecting the first node <xsl:apply-templates select="(//Item)[1]" mode="sum" /> Try this XSLT which demonstrates the various approaches <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl"> <xsl:output method="html" indent="yes" /> <xsl:template match="/"> <table border="1" id="CartTable" align="center"> <tr><th>Item Number</th> <th>Price</th> <th>Quantity</th> </tr> <xsl:for-each select="/Items/Item[QtyHold > 0]"> <tr> <td><xsl:value-of select="ItemID"/></td> <td>$<xsl:value-of select="ItemPrice"/></td> <td><xsl:value-of select="QtyHold"/></td> </tr> </xsl:for-each> <tr> <td ALIGN="center" COLSPAN="2">Total:</td> <xsl:variable name="itemTotals"> <xsl:for-each select="//Item[QtyHold >0]"> <total> <xsl:value-of select="ItemPrice * QtyHold" /> </total> </xsl:for-each> </xsl:variable> <td> <!-- XSLT 2.0 only: $<xsl:value-of select="sum(//Item[QtyHold >0]/(ItemPrice * QtyHold))"/>--> $<xsl:value-of select="sum(exsl:node-set($itemTotals)/total)"/> $<xsl:apply-templates select="(//Item)[1]" mode="sum" /> </td> </tr> </table> </xsl:template> <xsl:template match="Item" mode="sum"> <xsl:param name="runningTotal" select="0" /> <xsl:variable name="newTotal" select="$runningTotal + ItemPrice * QtyHold" /> <xsl:variable name="nextItem" select="following-sibling::Item[1]" /> <xsl:choose> <xsl:when test="$nextItem"> <xsl:apply-templates select="$nextItem" mode="sum"> <xsl:with-param name="runningTotal" select="$newTotal" /> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:value-of select="$newTotal" /> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> As a final thought, why don't you just a new Total element to each Item element in your XML. Initially, it would be set to 0, like QtyHold. Then, when you increment QtyHold by 1, by what ever process you do, you can also increment Total by the amount held in ItemPrice. That way, you can just sum this Total node to get the overall total, without the need for extension functions or recursive templates.
template not being called instead duplicates are called
I've the below XML File. <?xml version="1.0" encoding="UTF-8"?> <case lang="en" type="Report" source="original"> <case.head corrigendum="no"> <party.line corrigendum="no" lang="en"> <party role="Plaintiff">Calandra Shipping Co Ltd</party> <party role="Defendant">Noor Maritime Ltd</party> </party.line> <citation.group> <primary.citation>[2014] 2 HKLRD 242</primary.citation> <parallel.citation type="Unreported">[2014] HKEC 358</parallel.citation> <parallel.citation type="West.serial">2032232952</parallel.citation> <parallel.citation type="WL.cite">2014 WL 6336</parallel.citation> </citation.group> <court.line> <court type="court">CFI</court> </court.line> <case.ref.no.group> <case.ref.no> <prefix>HCAJ</prefix> <number>109</number> <year>2011</year> </case.ref.no> </case.ref.no.group> <judge.line type="chambers" lang="en"> <judge> <name>Peter Ng</name> <job.title prefix="no">J</job.title> </judge> </judge.line> <publication_date yyyymmdd="20140305"/> <date.group lang="en"> <date.line>Date of Hearing: <date yyyymmdd="20130918" significance="hearing" type="Unreported">18 September 2013</date></date.line> <date.line>Date of Decision: <date yyyymmdd="20130918" significance="judgment" type="Report">18 September 2013</date></date.line> </date.group> <counsel.group lang="en"> <counsel.line>Mr George Lamplough of Holman Fenwick Willan, for the plaintiff.</counsel.line> <counsel.line>Mr Kim Min Ju, instructed by Hart Giles, for the defendant.</counsel.line> </counsel.group> </case.head> <catchwords.group> <catchwords type="Report" lang="en"> <catchword level="1" index="yes" italic="no">Admiralty</catchword> <catchword level="2" index="yes" italic="no">collision claim</catchword> <catchword level="3" index="yes" italic="no">application for order under O.75 r.18(10) that plaintiff file particulars of damages and that damages be assessed before trial on liability</catchword> <catchword index="yes" italic="no">to be made to Registrar, not judge</catchword> <catchword index="yes" italic="no">trial on liability to occur before assessment of damages unless cogent reasons for reversal of order</catchword> <catchword index="yes" italic="no">Rules of the High Court (Cap.4A, Sub.Leg.) O.75 r.18(10)</catchword> </catchwords> <catchwords type="Report" lang="zh"> <catchword level="1" index="yes" italic="no">海事</catchword> <catchword level="2" index="yes" italic="no">有關碰撞的申索</catchword> <catchword level="3" index="yes" italic="no">根據第75號命令第18(10)條規則申請有關原告人存檔損害賠償的詳情以及在審訊法律責任事宜之前對損害賠償進行評估的命令</catchword> <catchword index="yes" italic="no">向司法常務官而不是向法官作出申請</catchword> <catchword index="yes" italic="no">除非具有力的理由逆轉相關的次序,否則法律責任事宜之審訊應於評估損害賠償之前進行</catchword> <catchword index="yes" italic="no">《高等法院規則》 (第4A章,附屬法例)第75號命令第18(10)條規則</catchword> </catchwords> </catchwords.group> <headnotes lang="en"> <para>P brought proceedings against D following a collision involving their ships. D applied to the Court for an order under O.75 r.18(10) of the Rules of the High Court (Cap.4A, Sub.Leg.) (RHC) that P file and serve on D particulars of the damages claimed and that damages be assessed prior to the trial on liability. Order 75 r.18(11) provides that where an order is made under r.18(10), the claim shall be treated as referred to the Registrar for assessment and rr.41 and 42 shall apply unless the Registrar otherwise directs.</para> <para> <emphasis type="bold">Held</emphasis>, dismissing the application, that:<list> <list.item><label>(1)</label>An application for the filing of particulars of damages and for assessment of damages under O.75 r.18(10) of the RHC shall be heard by the Registrar, even if it was made after the issue of a case management summons which shall be heard by a judge. (See paras.3, 5–6.)</list.item> <list.item><label>(2)</label>The Court would follow the RHC as far as possible, with suitable flexibility if the circumstances of the case warranted it. For this reason alone, the application was defective. (See para.7.)</list.item> <list.item><label>(3)</label>There was a more fundamental objection. It was long-established practice in collision actions for there to be a trial of liability first and then assessment of damages by the Registrar. The order would be reversed only for cogent reasons and none existed here. (See paras.9–12.)</list.item> <list.item><label>(4)</label>Further, O.75 r.18(10) and (11) went hand in hand. Given D’s concession that it was not seeking a reference to the Registrar for assessment of damages at this stage, there was no other legal basis to make an order under r.18(10). (See para.12.) <emphasis type="italic"></emphasis> </list.item></list> </para> <para.group> <heading>Application</heading> <para>This was an application by the defendant for an order under O.75 r.18(10) of the Rules of the High Court that the plaintiff file and serve on the defendant particulars of the damages claimed and that damages be assessed before the trial on liability in an action involving the collision of the parties’ respective ships. The facts are set out in the judgment.</para> </para.group> </headnotes> <ref.group> <leg.mentioned> <leg.ref country="Hong Kong" considered="yes"> <citetitle type="leg" full="Rules of the High Court (Cap.4A, Sub.Leg.)" legtype="sub_leg">Rules of the High Court (Cap.4A, Sub.Leg.)</citetitle> <leg.ptr.group> <leg.ptr provision="O." print="yes">75 rr.18(10)</leg.ptr> <leg.ptr provision="O.75 r." print="no">18(11)</leg.ptr> </leg.ptr.group> </leg.ref> <leg.ref country="Hong Kong" considered="yes"> <citetitle type="leg" full="《高等法院規則》 (第4A章,附屬法例)" legtype="sub_leg">《高等法院規則》 (第4A章,附屬法例)</citetitle> <leg.ptr.group> <leg.ptr provision="第" print="yes">75號命令第18(10)、18(11)條規則</leg.ptr> </leg.ptr.group> </leg.ref> <leg.ref country="Hong Kong" considered="no"> <citetitle type="leg" full="Rules of the High Court (Cap.4A, Sub.Leg.)" legtype="sub_leg">Rules of the High Court (Cap.4A, Sub.Leg.)</citetitle> <leg.ptr.group> <leg.ptr provision="O." print="yes">75 rr.18(10)</leg.ptr> <leg.ptr provision="O.75 r." print="no">18(11)</leg.ptr> <leg.ptr provision="O.75 r." print="no">25(1)(c)</leg.ptr> <leg.ptr provision="O.75 r." print="no">41</leg.ptr> <leg.ptr provision="O.75 r." print="no">42</leg.ptr> </leg.ptr.group> </leg.ref> </leg.mentioned> <other.mentioned> <other.ref type="Books"><author></author><book.title>Hong Kong Civil Procedure 2013</book.title><ed_vol>p.1319 para.75/41/2</ed_vol></other.ref> <other.ref type="Books"><author>Marsden</author><book.title>Collisions at Sea</book.title><ed_vol>(13th ed., 2003), para.18-01</ed_vol></other.ref> </other.mentioned> </ref.group> <judgment lang="en"> <judge.block> <heading align="left">Peter Ng J</heading> <para><label>1.</label> This is a collision action. The collision took place on 18 July 2011 in the East China Sea. It involved two ships, <emphasis type="italic">viz</emphasis> the Calandra owned by the plaintiff and the Rainbow owned by the defendant. The Rainbow sank as a result of the collision and the Calandra suffered damage. The parties have filed preliminary acts in which they blamed each other for the collision.</para> <para><label>2.</label> There is before me an application by the defendant for an order under O.75 r.18(10) of the Rules of the High Court that the plaintiff do file and serve on the defendant particulars of the damages claimed and that the damages be assessed prior to the trial on liability.</para> <para><label>3.</label> The rule clearly provides that the application must be made by summons to the Registrar even if it is made after the issue of a case management summons.</para> <para><label>4.</label> This is to be contrasted with O.75 r.25(1)(c) which says the Case Management Conference (CMC) shall be heard by a judge in person, unless a judge in person otherwise directs.</para> <para><label>5.</label> It seems to me the intention of the rules is reasonably clear: CMC must be heard by a judge, whereas an application for the filing of particulars of damages and for assessment of damages shall be heard by the Registrar. </para> <para><label>6.</label> The reason for this distinction is not difficult to understand: the matters to be dealt with at the CMC are directions for trial of liability which is always heard by a judge. The assessment of damages is normally heard by the Registrar. In fact, O.75 r.18(11) provides that where an order is made under para.10, the claim shall be treated as referred to the Registrar for assessment and rr.41 and 42 shall apply unless the Registrar otherwise directs. So it makes sense for the application under O.75 r.18(10) to be heard by the Registrar as he would have to follow it up if he decides to make an order. </para> <para><label>7.</label> The practice of this Court is to follow the rules as far as possible, with suitable flexibility if the circumstances of the case warrant it.</para> <para><label>8.</label> For that reason alone, the application is defective. </para> <para><label>9.</label> But I would not decide this application simply on such a basis. There is a more fundamental objection to the application. </para> <para><label>10.</label> It is a long-established practice of the English admiralty court, after liability has been determined, to refer to the Registrar the matter of assessment of damages: <emphasis type="italic">Hong Kong Civil Procedure 2013</emphasis> para.75/41/2. It is also the norm in collision actions for there to be a trial of liability first before assessment of damages: <emphasis type="italic">Marsden Collisions at Sea</emphasis> (13th ed., 2003), para.18-01.</para> <para><label>11.</label> If this order is to be reversed, it would only be reversed if cogent reasons are put forward. </para> <para><label>12.</label> No such reasons exist in the present case. No doubt, because of that, Mr Kim for the defendant very properly concedes that he is not seeking a reference to the Registrar for assessment of damages in the present case. But if he is not seeking a reference to the Registrar at this stage, there is no other legal basis for the defendant to seek particulars of damages. As I said, O.75 r.18(10) and (11) go hand in hand. Rule 18(11) provides that where an order is made under para.10, the claim shall be treated as referred to the Registrar for assessment. If the defendant is not seeking a reference to the Registrar, there is no legal justification to make an order under r.18(10) at all. </para> <para break="yes"><label>13.</label> For these reasons, I would dismiss the application.</para> <para.group> <heading align="right">Reported by Shin Su Wen</heading> </para.group> </judge.block> </judgment> </case> and the below XSLT. <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.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"> <xsl:output method="html"/> <xsl:template match="/"> <html> <head> <xsl:text disable-output-escaping="yes"><![CDATA[</meta>]]></xsl:text> <link rel="stylesheet" href="C:\Users\u0138039\Desktop\Proview\Periodicals\XSLTS\NEW_289.css" type="text/css"></link> </head> <body> <section class="tr_chapter"> <div class="chapter"> <xsl:apply-templates/> </div> </section> </body> </html> </xsl:template> <xsl:template match="case"> <xsl:apply-templates select="case.head"/> </xsl:template> <xsl:template match="case.head"> <div class="section-sect0"> <div class="para"> <xsl:value-of select="./party.line/party[#role='Plaintiff']"/> </div> </div> <div class="section-sect0"> <div class="para"> <xsl:text disable-output-escaping="yes">and</xsl:text> </div> </div> <div class="section-sect0"> <div class="para"> <xsl:value-of select="./party.line/party[#role='Defendant']"/> </div> </div> <xsl:apply-templates select="court.line|case.ref.no.group |judge.line|judgement"/> </xsl:template> <xsl:template match="para"> <div class="para"> <xsl:apply-templates/> </div> </xsl:template> <xsl:template match="court.line"> <hr></hr> <br /> <div class="align-center"> <xsl:text>(</xsl:text> <xsl:choose> <xsl:when test="contains(./court/text(),'CFI')"> <xsl:text>Court of First Instance</xsl:text> </xsl:when> <xsl:when test="contains(./court/text(),'CA')"> <xsl:text>Court of Appeal</xsl:text> </xsl:when> </xsl:choose> <xsl:text>)</xsl:text> </div> </xsl:template> <xsl:template match="case.ref.no.group" name="new"> <xsl:for-each select="case.ref.no"> <div class="align-center"> <xsl:text>(</xsl:text> <xsl:choose> <xsl:when test="contains(./prefix,'HCAJ')"> <xsl:text>Admiralty Action No </xsl:text> </xsl:when> <xsl:when test="contains(./prefix,'HCAL')"> <xsl:text>Constitutional and Administrative Law List No </xsl:text> </xsl:when> <xsl:when test="contains(./prefix,'CAAR')"> <xsl:text>Application for Review No </xsl:text> </xsl:when> <xsl:when test="contains(./prefix,'CACV')"> <xsl:text>Civil Appeal No </xsl:text> </xsl:when> <xsl:when test="contains(./prefix,'HCMP')"> <xsl:text>Miscellaneous Proceedings No </xsl:text> </xsl:when> <xsl:when test="contains(./prefix,'HCMA')"> <xsl:text>Magistracy Appeal No </xsl:text> </xsl:when> </xsl:choose> <xsl:value-of select="./number"/> <xsl:text> of </xsl:text> <xsl:value-of select="./year"/> <xsl:text>)</xsl:text> </div> </xsl:for-each> <br /> <hr></hr> </xsl:template> <xsl:template match="judge.line"> <div class="section-sect3"> <xsl:for-each select="judge"> <xsl:value-of select="name"/> <xsl:text> </xsl:text> <xsl:value-of select="job.title"/> <xsl:if test="not(position() = last())"> <xsl:text>,</xsl:text> </xsl:if> </xsl:for-each> <xsl:text> in </xsl:text> <xsl:value-of select="concat(upper-case(substring(./#type,1,1)),substring(./#type,2))"/> </div> <xsl:apply-templates select="following-sibling::date.group"></xsl:apply-templates> </xsl:template> <xsl:template match="date.group"> <div class="section-sect4"> <div class="para"> <xsl:value-of select="./date.line/date"/> </div> </div> <xsl:apply-templates select="//catchwords.group/catchwords[#lang='en']"/> <xsl:apply-templates select="//ref.group" mode="x"/> </xsl:template> <xsl:template match="catchwords.group/catchwords[#lang='en']"> <div class="y"> <xsl:for-each select="catchword"> <xsl:choose> <xsl:when test="#level=1"><br/> <span class="font-style-bolditalic"> <xsl:value-of select="."/> </span> <xsl:text disable-output-escaping="yes">-</xsl:text> </xsl:when> <xsl:otherwise> <xsl:for-each select="."> <xsl:value-of select="."></xsl:value-of> <xsl:if test="not(position() = last()-1)"> <xsl:text disable-output-escaping="yes"> – </xsl:text> </xsl:if> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:for-each> </div> </xsl:template> <xsl:template match="ref.group/leg.mentioned" mode="x"> <xsl:for-each select="./leg.ref"> <xsl:if test="./#considered='yes'"> <div class="para"> <xsl:value-of select="citetitle"/> <xsl:text>, </xsl:text> <xsl:for-each select="./leg.ptr.group/leg.ptr"> <xsl:value-of select="."/> <xsl:if test="not(position() = last())"> <xsl:text disable-output-escaping="yes">, </xsl:text> </xsl:if> </xsl:for-each> </div> </xsl:if> </xsl:for-each> <xsl:apply-templates select="//catchwords.group/catchwords[#lang='zh']"/> </xsl:template> <xsl:template match="catchwords.group/catchwords[#lang='zh']"> <div class="y"> <xsl:for-each select="catchword"> <xsl:choose> <xsl:when test="#level=1"><br/> <span class="font-style-bolditalic"> <xsl:value-of select="."/> </span> <xsl:text disable-output-escaping="yes">-</xsl:text> </xsl:when> <xsl:otherwise> <xsl:for-each select="."> <xsl:value-of select="."></xsl:value-of> <xsl:if test="not(position() = last()-1)"> <xsl:text disable-output-escaping="yes"> – </xsl:text> </xsl:if> </xsl:for-each> </xsl:otherwise> </xsl:choose> </xsl:for-each> </div> <xsl:apply-templates select="//headnotes"/> </xsl:template> <xsl:template match="headnotes/para"> <xsl:choose> <xsl:when test="position()=1"> <div class="x"> <xsl:apply-templates></xsl:apply-templates> </div> </xsl:when> <xsl:otherwise> <div class="m"> <xsl:apply-templates/> </div> </xsl:otherwise> </xsl:choose> <xsl:apply-templates select="para.group"/> </xsl:template> <xsl:template match="para.group"> <div class="section-sect1"> <xsl:value-of select="./heading"/> </div> <xsl:for-each select="./para"> <div class="para"> <xsl:apply-templates select="node()[not(self::label)]"/> </div> </xsl:for-each> <xsl:apply-templates select="//counsel.group"/> </xsl:template> <xsl:template name="orderedlist" match="list"> <ol class="eng-orderedlist orderedlist"> <xsl:apply-templates select="list.item/label"/> </ol> </xsl:template> <xsl:template name="orderitempara" match="list.item/label"> <li class="item"> <div class="para"> <span class="item-num"> <xsl:choose> <xsl:when test="following-sibling::case.considered"> <xsl:apply-templates/> </xsl:when> <xsl:otherwise> <xsl:value-of select="."/> </xsl:otherwise> </xsl:choose> </span> <xsl:apply-templates select="parent::list.item"/> </div> </li> </xsl:template> <xsl:template match="list.item"> <xsl:variable name="a"> <xsl:value-of select="./label"/> </xsl:variable> <xsl:choose> <xsl:when test="./label"> <xsl:apply-templates select="child::node()[not(self::label|case.ref)]"/> </xsl:when> </xsl:choose> </xsl:template> <xsl:template match="counsel.group" name="j"> <xsl:for-each select="./counsel.line"> <div class="para"> <xsl:value-of select="."/> </div> </xsl:for-each> <xsl:apply-templates select="//ref.group/leg.mentioned" mode="y"/> </xsl:template> <xsl:template match="ref.group/leg.mentioned" mode="y"> <xsl:for-each select="./leg.ref"> <xsl:if test="./#considered='no'"> <div class="section-sect1"> <xsl:text>Legislation mentioned in the judgment</xsl:text> </div> <div class="para"> <xsl:value-of select="citetitle"/> <xsl:text>, </xsl:text> <xsl:for-each select="./leg.ptr.group/leg.ptr"> <xsl:value-of select="."/> <xsl:if test="not(position() = last())"> <xsl:text disable-output-escaping="yes">, </xsl:text> </xsl:if> </xsl:for-each> </div></xsl:if> </xsl:for-each> <xsl:choose> <xsl:when test="following-sibling::other.mentioned"> <div class="section-sect1"> <xsl:text>Other materials mentioned in the judgment</xsl:text> </div> <xsl:apply-templates select="following-sibling::other.mentioned"/> </xsl:when> <xsl:otherwise> <div class="section-sect1"> <xsl:text>Cases cited in the judgment</xsl:text> </div> <xsl:apply-templates select="//case.considered"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="other.mentioned"> <xsl:for-each select="other.ref"> <div class="para"> <xsl:if test="./author/text()"> <xsl:value-of select="./author"/> <xsl:text>, </xsl:text> </xsl:if> <span class="font-style-italic"> <xsl:value-of select="./book.title"/> </span> <xsl:text> </xsl:text> <xsl:value-of select="./ed_vol"/> </div> </xsl:for-each> </xsl:template> <xsl:template match="case.considered"> <xsl:for-each select="."> <div class="para"> <xsl:if test="./case.ref"> <span class="font-style-italic"> <xsl:value-of select="./case.ref/citetitle[#full]"/></span> <xsl:text> </xsl:text> <xsl:value-of select="./case.ref/citecitation/#full"/> </xsl:if></div> </xsl:for-each> </xsl:template> <xsl:template match="judgment"> <div class="section-sect1"> <xsl:value-of select="./judge.block/heading"/> </div> <xsl:for-each select="./judge.block/para"> <div class="para"> <span class="new"> <xsl:value-of select="./label"></xsl:value-of> </span> <xsl:apply-templates select="child::node()[not(self::label)]"/> </div> </xsl:for-each> <xsl:for-each select="./judge.block/para.group"> <xsl:if test="./heading"> <div class="section-sect1"> <xsl:value-of select="./heading/text()"/> </div> </xsl:if> <xsl:for-each select="para"> <div class="para"> <span class="new"> <xsl:value-of select="./label"></xsl:value-of> </span> <!--<xsl:value-of select="./text()"/>--> <xsl:apply-templates select="child::node()[not(self::label)]"/> </div> <xsl:apply-templates select="./list"/> </xsl:for-each> </xsl:for-each> </xsl:template> <xsl:template match="block.quote"> <xsl:choose> <xsl:when test="./list"> <xsl:apply-templates select="list"/> </xsl:when> <xsl:when test="./para"><xsl:for-each select="./para"> <div class="extract"> <xsl:apply-templates select="."/> </div> </xsl:for-each></xsl:when> <xsl:when test="./para.group"> <xsl:for-each select="./para.group"> <div class="ali-itl"> <xsl:value-of select="./heading"/> </div> <xsl:choose> <xsl:when test="./para.group"><xsl:for-each select="./para.group"> <xsl:if test="./para"> <div class="ali-itl"> <xsl:value-of select="./heading"/> </div> <div class="extract"> <div class="para"><xsl:if test="./para/label"> <div class="new"> <xsl:value-of select="./para.group/para/label"/> </div></xsl:if> <xsl:apply-templates select="./para/text()"/> </div></div></xsl:if> </xsl:for-each> </xsl:when> <xsl:otherwise> <div class="extract"> <div class="para"><xsl:if test="./para/label"> <div class="new"> <xsl:value-of select="./para.group/para/label"/> </div></xsl:if> <xsl:apply-templates select="./para/text()"/> </div></div> </xsl:otherwise> </xsl:choose> </xsl:for-each></xsl:when> </xsl:choose> </xsl:template> <xsl:template match="emphasis"> <xsl:choose> <xsl:when test="citetitle"> <span class="font-style-italic"> <xsl:apply-templates select="./list.item"/> </span> </xsl:when> <xsl:when test="./#type"> <xsl:variable name="fontStyle"> <xsl:value-of select="concat('font-style-',#type)"/> </xsl:variable> <span class="{$fontStyle}"> <xsl:apply-templates/> </span> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> here i'm trying to call judgement template, but it is not getting called but when i'm debugging, there were some default templates getting called, please let me know how to call judgement template. Thanks
That is because judgement is not a child of case.head. Moreover, the only element present is judgment replace the following line <xsl:apply-templates select="court.line|case.ref.no.group |judge.line|judgement"/> with <xsl:apply-templates select="court.line|case.ref.no.group |judge.line|../judgment"/>
split a number and create an orderedlist
<orderedlist type="manual"> <item num="8. (1)"> <para id="t2_HKWB-S2-1.1_pgfId-135">What is your present estimate of the length of trial?</para> </item> <item num="(2)"> <para id="t2_HKWB-S2-1.1_pgfId-136">What is the earliest date that you believe you can be ready for trial?</para> </item> </orderedlist> This is a slight tricky one as here, first the number 8. (1) should be split. 8 should be in an orderedlist and then 1 and 2 should be in same orderedlist(nested), under the main orderedlist, please let me know how i can achieve this. i'm already trying with an xsl and it is as below. <xsl:template name="orderedlist" match="orderedlist"> <ol class="eng-orderedlist orderedlist"> <xsl:apply-templates/> </ol> </xsl:template> <xsl:template name="orderitem" match="item"> <li class="item"> <xsl:apply-templates/> </li> </xsl:template> <xsl:template name="orderitempara" match="item/para"> <div class="para"> <xsl:choose> <xsl:when test="position()=1"> <span class="item-num"> <xsl:if test="position()=1"> <xsl:value-of select="parent::item[1]/#num"/> </xsl:if> </span> <xsl:text> </xsl:text> <xsl:apply-templates/> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </div> </xsl:template> But the output i get is like below: 8. (1)What is your present estimate of the length of trial? (2)What is the earliest date that you believe you can be ready for trial? should look something like this. 8 (1)What is your present estimate of the length of trial? (2)What is the earliest date that you believe you can be ready for trial? Thanks
XSLT 1.0 How to match a string to another, list it, and under a different heading, list the unmatched string (specific situation)
I have been training myself in XSLT for about 1.5 months. I have made a simplified shorter version of what I am having trouble figuring out, and would highly appreciate any help at all as I am stuck on the issue. Thanks! Basic Situation: There's a string in a root attribute with an ancestor of element definition xpath: /v3:QualityMeasureDocument/v3:component/v3:dataCriteriaSection/v3:definition/v3:valueSet/v3:id/#root ...that when matched with the id from a valueSet attribute with an ancestor of element entry, xpath: /v3:QualityMeasureDocument/v3:component/v3:dataCriteriaSection/v3:entry/v3:observationCriteria/v3:value/#valueSet or /v3:QualityMeasureDocument/v3:component/v3:dataCriteriaSection/v3:entry/v3:observationCriteria/v3:code/#valueSet the output (needs to and currently does) display the string, along with its required attribute(s). However, when there is no match for the string in these locations, the string must also be listed, with a 'Not Specified' header. THE ERROR: The 'Not Specified' header and its string are being listed even when all of the existing strings match. In this scenario, there should only be matched strings listed. The Problem Translator (XSL file) : <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" xmlns:v3="urn:hl7-org:v3" xmlns:rvs="urn:ihe:iti:svs:2008"> <xsl:output method="html" standalone="yes" omit-xml-declaration="no" indent="yes" xalan:indent-amount="2"/> <xsl:template match="/v3:QualityMeasureDocument"> <html> <head> <title>Test 'I'</title> </head> <body> <ul> <xsl:apply-templates select="//v3:dataCriteriaSection" /> </ul> </body> </html> </xsl:template> <xsl:template match="v3:dataCriteriaSection"> <xsl:for-each select="//v3:entry"> <xsl:if test="*/v3:value/#valueSet"> <xsl:call-template name="definitionValueSet"> <xsl:with-param name="cur_valueSetID" select="*/v3:value/#valueSet"/> </xsl:call-template> </xsl:if> <xsl:if test="*/v3:code/#valueSet"> <xsl:call-template name="definitionValueSet"> <xsl:with-param name="cur_valueSetID" select="*/v3:code/#valueSet"/> </xsl:call-template> </xsl:if> <xsl:if test="*/v3:participant/v3:roleParticipant/v3:code/#valueSet"> <xsl:call-template name="definitionValueSet"> <xsl:with-param name="cur_valueSetID" select="*/v3:participant/v3:roleParticipant/v3:code/#valueSet"/> </xsl:call-template> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template name="definitionValueSet"> <xsl:param name="cur_valueSetID"/> <xsl:for-each select="//v3:valueSet"> <xsl:choose> <xsl:when test="$cur_valueSetID != v3:id/#root or not( v3:text/v3:reference[starts-with(#value, 'https://') and contains(#value, $cur_valueSetID)] ) or not( v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/#id = $cur_valueSetID )"> <xsl:if test="not($cur_valueSetID = '')"> <li> <xsl:text>Not Specified</xsl:text> <ul> <li> <xsl:text>ValueSet: </xsl:text> <xsl:value-of select="$cur_valueSetID"></xsl:value-of> </li> </ul> </li> </xsl:if> </xsl:when> <xsl:when test="v3:id/#root = $cur_valueSetID"> <xsl:if test="v3:text/v3:reference[starts-with(#value, 'https://') and contains(#value, $cur_valueSetID)]"> <xsl:if test="v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/#id = $cur_valueSetID"> <li> <xsl:text>Id: </xsl:text> <xsl:value-of select="v3:id/#root"/> <xsl:for-each select="v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/rvs:ConceptList/rvs:Concept"> <ul> <li> <xsl:if test="not(#code = '')"> <xsl:if test="#code"> <xsl:text>code = </xsl:text> <xsl:value-of select="#code"></xsl:value-of> <xsl:text> </xsl:text> </xsl:if> </xsl:if> </li> </ul> </xsl:for-each> </li> </xsl:if> </xsl:if> </xsl:when> </xsl:choose> </xsl:for-each> </xsl:template> </xsl:stylesheet> XML input file 'I' xml : <?xml version="1.0" encoding="UTF-8"?> <QualityMeasureDocument xmlns="urn:hl7-org:v3"> <component> <dataCriteriaSection> <definition> <valueSet> <!-- Value Set for Race --> <id root='1.1.1.1.1.1.1' /> <text> <reference value='https://localhost/RetrieveValueSet?id=1.1.1.1.1.1.1' /> <RetrieveValueSetResponse xmlns="urn:ihe:iti:svs:2008"> <ValueSet id="1.1.1.1.1.1.1"> <ConceptList> <Concept code="4" /> <Concept code="5" /> <Concept code="6" /> </ConceptList> </ValueSet> </RetrieveValueSetResponse> </text> </valueSet> </definition> <definition> <valueSet> <id root='1.1.1.1.1.1.2' /> <text> <reference value='https://localhost/RetrieveValueSet?id=1.1.1.1.1.1.2' /> <RetrieveValueSetResponse xmlns="urn:ihe:iti:svs:2008"> <ValueSet id="1.1.1.1.1.1.2"> <ConceptList> <Concept code="007.2" /> <Concept code="007.3" /> </ConceptList> </ValueSet> </RetrieveValueSetResponse> </text> </valueSet> </definition> <entry> <observationCriteria> <code code="424144002" codeSystem="123123213" displayName="FEWFW" /> <value> <low /> <high /> </value> </observationCriteria> </entry> <entry> <observationCriteria> <code code="DFHKJ" codeSystem="ASKJDHK" displayName="ASDNJK" /> <value> <width /> </value> </observationCriteria> </entry> <entry> <observationCriteria> <code code="FDSFD" codeSystem="JHBHJB" displayName="HJGJH" /> <value valueSet="1.1.1.1.1.1.1" /> </observationCriteria> </entry> <entry> <encounterCriteria> <code valueSet="1.1.1.1.1.1.2" /> </encounterCriteria> </entry> </dataCriteriaSection> </component> </QualityMeasureDocument> Expected Output Code 'I' HTML : <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <html xmlns:xalan="http://xml.apache.org/xalan" xmlns:rvs="urn:ihe:iti:svs:2008" xmlns:v3="urn:hl7-org:v3"> <head> <title>Test 'I'</title> </head> <body> <ul> <li>Id: 1.1.1.1.1.1.1 <ul> <li>code = 4 </li> </ul> <ul> <li>code = 5 </li> </ul> <ul> <li>code = 6 </li> </ul> </li> <li>Id: 1.1.1.1.1.1.2 <ul> <li>code = 007.2 </li> </ul> <ul> <li>code = 007.3 </li> </ul> </li> </ul> </body> </html> It would be simple to create the correct output through a hack, or just erasing code, but this needs to work in all situations. Such as, having no matches at all and displaying only the 'Not Specified' header and its string each time it occurs, or a mixture of both situations. The code currently works in a situation where there are no matches, and displays the 'Not Specified' header and its string each time it occurs. It seems like if this could be done, "if it's not a match AND hasn't already been listed" it would solve the problem. Hope that helps. If you would like more information or more files let me know. Any tips at all would be great! Thanks.
I think the main problem you are having is within your named template "definitionValueSet", where you loop over valueSet elements with an xsl:for-each <xsl:for-each select="//v3:valueSet"> Within this you test whether the relevant attributes match your current parameter, and if you find a match, you output your list. But all valueSet elements will be searched, so even if one matches, you are still going to be processing the ones that don't and so your xsl:if for a non-match is called too. This results in the "Not Specified" being output. What you really need to be doing is matching only the valueSet element if it exists, and if none exist that match, output your "Not Specified". One way to do this is to first create a variable that holds the unique id of the valueSet element that matches <xsl:variable name="valueSet"> <xsl:value-of select="generate-id(//v3:valueSet[v3:id/#root = $cur_valueSetID and v3:text/v3:reference[starts-with(#value, 'https://') and contains(#value, $cur_valueSetID)] and v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/#id = $cur_valueSetID])"/> </xsl:variable> Then, you can test whether this has been set, and if so, apply the template for that element. If not set, you can have your not-specified code <xsl:choose> <xsl:when test="$valueSet"> <xsl:apply-templates select="//v3:valueSet[generate-id() = $valueSet]"/> </xsl:when> <xsl:otherwise> <!-- Not Specified --> </xsl:otherwise> </xsl:choose> Here is the full XSLT, which should hopefully give the output you require <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" xmlns:v3="urn:hl7-org:v3" xmlns:rvs="urn:ihe:iti:svs:2008"> <xsl:output method="html" standalone="yes" omit-xml-declaration="no" indent="yes" xalan:indent-amount="2"/> <xsl:template match="/v3:QualityMeasureDocument"> <html> <head> <title>Test 'I'</title> </head> <body> <ul> <xsl:apply-templates select="//v3:dataCriteriaSection"/> </ul> </body> </html> </xsl:template> <xsl:template match="v3:dataCriteriaSection"> <xsl:for-each select=".//v3:entry"> <xsl:if test="*/v3:value/#valueSet"> <xsl:call-template name="definitionValueSet"> <xsl:with-param name="cur_valueSetID" select="*/v3:value/#valueSet"/> </xsl:call-template> </xsl:if> <xsl:if test="*/v3:code/#valueSet"> <xsl:call-template name="definitionValueSet"> <xsl:with-param name="cur_valueSetID" select="*/v3:code/#valueSet"/> </xsl:call-template> </xsl:if> <xsl:if test="*/v3:participant/v3:roleParticipant/v3:code/#valueSet"> <xsl:call-template name="definitionValueSet"> <xsl:with-param name="cur_valueSetID" select="*/v3:participant/v3:roleParticipant/v3:code/#valueSet"/> </xsl:call-template> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template name="definitionValueSet"> <xsl:param name="cur_valueSetID"/> <xsl:variable name="valueSet"> <xsl:value-of select="generate-id(//v3:valueSet[v3:id/#root = $cur_valueSetID and v3:text/v3:reference[starts-with(#value, 'https://') and contains(#value, $cur_valueSetID)] and v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/#id = $cur_valueSetID])"/> </xsl:variable> <xsl:choose> <xsl:when test="$valueSet != ''"> <xsl:apply-templates select="//v3:valueSet[generate-id() = $valueSet]"/> </xsl:when> <xsl:otherwise> <li> <xsl:text>Not Specified</xsl:text> <ul> <li> <xsl:text>ValueSet: </xsl:text> <xsl:value-of select="$cur_valueSetID"/> </li> </ul> </li> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="v3:valueSet"> <li> <xsl:text>Id: </xsl:text> <xsl:value-of select="v3:id/#root"/> <xsl:for-each select="v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/rvs:ConceptList/rvs:Concept"> <ul> <li> <xsl:if test="not(#code = '')"> <xsl:if test="#code"> <xsl:text>code = </xsl:text> <xsl:value-of select="#code"/> <xsl:text/> </xsl:if> </xsl:if> </li> </ul> </xsl:for-each> </li> </xsl:template> </xsl:stylesheet> Do note, as mentioned in a comment, be careful with the use of expression //v3:entry. This is an absolute expression, and will match any element at all in the document (i.e it searches from the root element downwards). If you wanted only to look under the current element, use the relative expression .//v3:entry EDIT: For a slight variant on this, as a potentially more efficient way to look up the valueSet elements you could define a key at the top of the XSLT document <xsl:key name="valueSet" match="v3:valueSet" use="generate-id()" /> Then, instead of doing this to look up the correct valueSet element <xsl:apply-templates select="//v3:valueSet[generate-id() = $valueSet]"/> You could use the key instead <xsl:apply-templates select="key('valueSet', $valueSet)"/>
The following is a simple-ish alternate solution (does not use generate-id() or key() ) provided for comprehension. It is likely less efficient than and should not replace Tim C's excellent answer. I am simply providing this so people can learn, and to show that I put full effort into solving this issue, instead of just getting what I needed and moving on. The solution is a fix to the original 'Problem Translator'. The only section that needs to be edited (although heavily) from that XSL file is the "definitionValueSet" named template. First we need to create a variable $valueSetData which stores all of the values of v3:id/#root in a one time pass, with a ',' in between them, in order to be individually referenced later. It's like a new temporary database. The for-each contains a predicate which limits the matches as per requirements. These are included within the declaration because they are local nodes there. Also, this keeps from processing extra conditional checks later. <xsl:variable name="valueSetData"> <xsl:for-each select="//v3:valueSet[ v3:text/v3:reference[starts-with(#value, 'https://') and contains(#value, $cur_valueSetID)] and v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/#id = $cur_valueSetID]"> <xsl:value-of select="v3:id/#root"/> <xsl:text>,</xsl:text> </xsl:for-each> </xsl:variable> Next we have the choose statement, edited for specifics. The statement determines if there is a match to the $cur_valueSetID within the $valueSetData 'database'. The for-each predicate limits duplicate matches (with the wrong values in addition due to context). <xsl:choose> <xsl:when test="contains($valueSetData, $cur_valueSetID)"> <xsl:for-each select="//v3:valueSet[$cur_valueSetID = v3:id/#root]"> <!-- Display found matches which meet all requirements --> </xsl:for-each> </xsl:when> <xsl:otherwise> <!-- Display Not Specified --> </xsl:otherwise> </xsl:choose> The full "definitionValueSet" template: <xsl:template name="definitionValueSet"> <xsl:param name="cur_valueSetID"/> <xsl:variable name="valueSetData"> <xsl:for-each select="//v3:valueSet[ v3:text/v3:reference[starts-with(#value, 'https://') and contains(#value, $cur_valueSetID)] and v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/#id = $cur_valueSetID]"> <xsl:value-of select="v3:id/#root"/> <xsl:text>,</xsl:text> </xsl:for-each> </xsl:variable> <xsl:choose> <xsl:when test="contains($valueSetData, $cur_valueSetID)"> <xsl:for-each select="//v3:valueSet[$cur_valueSetID = v3:id/#root]"> <li> <xsl:text>Id: </xsl:text> <xsl:value-of select="v3:id/#root"/> <xsl:for-each select="v3:text/rvs:RetrieveValueSetResponse/rvs:ValueSet/rvs:ConceptList/rvs:Concept"> <ul> <li> <xsl:if test="not(#code = '')"> <xsl:if test="#code"> <xsl:text>code = </xsl:text> <xsl:value-of select="#code"></xsl:value-of> <xsl:text/> </xsl:if> </xsl:if> </li> </ul> </xsl:for-each> </li> </xsl:for-each> </xsl:when> <xsl:otherwise> <li> <xsl:text>Not Specified</xsl:text> <ul> <li> <xsl:text>ValueSet: </xsl:text> <xsl:value-of select="$cur_valueSetID"></xsl:value-of> </li> </ul> </li> </xsl:otherwise> </xsl:choose> </xsl:template>