I've the below XML.
<orderedlist type="manual">
<item num="1."><para>identify the issues in dispute;</para></item>
<item num="1.1"><para>explore and generate options;</para></item>
<item num="1.1.1"><para>communicate with one another; and/or</para></item>
<item num="(i)"><para>copy of the cancellation of employment pass; and</para></item>
<orderedlist>
here i want to translate all the . to - in item-num and surround them with a different tag, where there is some number or period after . previously I've received a solution and I've used not(ends-with(./#num,'.')). That worked fine till some point, recently I've came across a situation(4th item num in the above XML) where in the item num has values like (i), i, a, a), and these also satisfy the condition and are getting the new tag. below is my XSL template.
<xsl:template name="orderedlist" match="orderedlist">
<ol class="eng-orderedlist orderedlist">
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template match="item">
<xsl:call-template name="paran"></xsl:call-template>
</xsl:template>
<xsl:template name="paran">
<xsl:apply-templates select="./para/node()[1][self::page]" mode="first"/>
<li class="item">
<div class="para">
<xsl:choose>
<xsl:when test="not(ends-with(./#num,'.'))">
<a name="{translate(./#num,'.','-')}"/>
<span class="phrase">
<xsl:value-of select="./#num"></xsl:value-of>
</span>
</xsl:when>
<xsl:when test="./#num">
<span class="item-num">
<xsl:value-of select="./#num"></xsl:value-of>
</span>
</xsl:when>
</xsl:choose>
<xsl:apply-templates/>
</div>
</li>
</xsl:template>
<xsl:template match="page[not(preceding-sibling::node()[not(self::text()) or normalize-space()])]"/>
here i don't want phrase around other numbers than i format X.X X.X.X.
you can find a demo of this issue here.
please let me know how can i fix it.
Thanks
Perhaps you need to add a check on whether the num attribute contains a full-stop in the first place
<xsl:when test="contains(#num, '.') and not(ends-with(./#num,'.'))">
i.e. #num contains a full-stop, but not one at the end.
I'd suggest you do it this way:
<xsl:template match="item">
<!-- do one thing here -->
</xsl:template>
<xsl:template match="item [not(ends-with(#num, '.'))] [not (translate(#num, '.123456789', ''))]">
<!-- do another thing here -->
</xsl:template>
--
Doing the predicate by regex as suggested by Ian Roberts would probably be more elegant.
Using XSLT 1.0 with an RSS calendar feed, I want to exclude expired items - those with pubDates before the current date - then include only three current items. The result should be the next three future events. I used http://exslt.org/date/index.html to create a variable for the current system date. The problem is that when I select="item[not(position() > 4)] and substring(item/pubDate,5,11) >= $current", I end up with less than three items if any of the first ones are expired. Apparently my code selects three items then removes the expired ones, which is not what I want. Is it possible to save a copy of the unexpired items and then select three of them?
Since XSLT 1.0 doesn't provide inequality string comparison operators, I may not be able to see if a value such as "30 Oct 2013" is greater than "29 Oct 2013," I can format the values as 30102013 and 29102013 instead, but it still seems that I'm trying to concatenate channel/item/pubDate before I have selected it. So knowing how to process the XML/RSS in two stages, if possible, would be helpful.
I have tried several techniques, with similar results:
<xsl:for-each select="substring(item/pubDate,5,11) >= $current and item[not(position() > 4)]">
<xsl:template match="item[not(position() > 4)]">
<xsl:apply-templates select="item"/>
<xsl:for-each select="substring(item/pubDate,5,11) >= $current">
<xsl:if test=" item[not(position() > 4)]">
Sample XML:
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:link href="http://calendar.example.edu/" rel="self" type="application/rss+xml"/>
<title>University Calendar - Featured Events</title>
<link>http://calendar.example.edu/</link>
<description>List of featured events on calendar.example.edu</description>
<language>en-us</language>
<pubDate>Tue, 27 Oct 2013 20:47:05 CDT</pubDate>
<item>
<title>Creative Movement Program Student Show</title>
<description/>
<link>http://calendar.example.edu/?&y=2013&m=10&d=30&eventdatetime_id=19721</link>
<guid>calendar.example.edu/?&y=2013&m=10&d=30&eventdatetime_id=19721</guid>
<pubDate>Wed 30 Oct 2013, 17:00:00 CDT</pubDate>
</item>
<item>
<title>Philosophy Career Fair</title>
<description>The Department of Philosophy brings recruiters from around the state to interview seniors and alumni.</description>
<link>http://calendar.example.edu/?&y=2013&m=11&d=04&eventdatetime_id=16427</link>
<guid>calendar.example.edu/?&y=2013&m=11&d=04&eventdatetime_id=16427</guid>
<pubDate>Mon 04 Nov 2013, 07:00:00 CDT</pubDate>
</item>
<item>
<title>Football vs. Caltech</title>
<description/>
<link>http://calendar.example.edu/?&y=2013&m=12&d=07&eventdatetime_id=16521</link>
<guid>calendar.example.edu/?&y=2013&m=12&d=07&eventdatetime_id=16521</guid>
<pubDate>Sat 07 Dec 2013, 00:00:00 CDT</pubDate>
</item>
<item>
<title>Mural Exhibition</title>
<description>The College of Arts presents an overview of wall paintings from the Caves of Lascaux to the Kiev train station.</description>
<link>http://calendar.example.edu/?&y=2014&m=01&d=14&eventdatetime_id=16759</link>
<guid>calendar.example.edu/?&y=2014&m=01&d=14&eventdatetime_id=16759</guid>
<pubDate>Tue 14 Jan 2014, 07:00:00 CDT</pubDate>
</item>
</channel>
</rss>
Current XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" extension-element-prefixes="date" version="1.0" xmlns:date="http://exslt.org/dates-and-times" >
<xsl:template name="lf">
<xsl:text/>
</xsl:template>
<xsl:template match="rss">
<section id="campusEvents" role="region">
<h2 id="eventsTitle">
Campus Events
</h2>
<xsl:apply-templates select="channel"/>
<div class="moreLink">
Full Calendar
</div>
</section>
</xsl:template>
<xsl:template match="channel">
<xsl:variable name="currDay" select="substring(date:date(),9,2)"/>
<xsl:variable name="currMonth">
<xsl:call-template name="format-month">
<xsl:with-param name="date" select="date:date()"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="currYear" select="substring(date:date(),1,4)"/>
<xsl:variable name="current" select="concat($currDay,' ',$currMonth,' ',$currYear )"/>
<xsl:for-each select="item[not(position() > 4)] and substring(item/pubDate,5,11) >= $current">
<div class="eventBlock">
<xsl:call-template name="lf"/>
<div class="dateBlock">
<xsl:call-template name="lf"/>
<div class="eventMonth">
<xsl:value-of select="substring(pubDate,8,3)"/>
</div>
<div class="eventDate">
<xsl:value-of select="substring(pubDate,5,2)"/>
</div>
</div>
<xsl:call-template name="lf"/>
<div class="eventDescription">
<a class="url" href="{link}">
<xsl:value-of select="title"/>
</a>
<xsl:call-template name="lf"/>
</div>
<xsl:call-template name="lf"/>
</div>
<xsl:call-template name="lf"/>
</xsl:for-each>
</xsl:template>
<xsl:template name="format-month">
<xsl:param name="date"/>
<xsl:variable name="monthName" select="substring(date:date(),6,2)"/>
<xsl:variable name="month">
<xsl:choose>
<xsl:when test="$monthName = '01'">Jan</xsl:when>
<xsl:when test="$monthName = '02'">Feb</xsl:when>
<xsl:when test="$monthName = '03'">Mar</xsl:when>
<xsl:when test="$monthName = '04'">Apr</xsl:when>
<xsl:when test="$monthName = '05'">May</xsl:when>
<xsl:when test="$monthName = '06'">Jun</xsl:when>
<xsl:when test="$monthName = '07'">Jul</xsl:when>
<xsl:when test="$monthName = '08'">Aug</xsl:when>
<xsl:when test="$monthName = '09'">Sep</xsl:when>
<xsl:when test="$monthName = '10'">Oct</xsl:when>
<xsl:when test="$monthName = '11'">Nov</xsl:when>
<xsl:when test="$monthName = '12'">Dec</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="$month"/>
</xsl:template>
</xsl:stylesheet>
Desired Result (after Oct. 30 event has expired):
<section role="region" id="campusEvents">
<h2 id="eventsTitle">
Campus Events
</h2>
<div class="eventBlock">
<div class="dateBlock">
<div class="eventMonth">Nov</div>
<div class="eventDate">04</div>
</div>
<div class="eventDescription">
Philosophy Career Fair
</div>
</div>
<div class="eventBlock">
<div class="dateBlock">
<div class="eventMonth">Dec</div>
<div class="eventDate">07</div>
</div>
<div class="eventDescription">
Football vs. Caltech
</div>
</div>
<div class="eventBlock">
<div class="dateBlock">
<div class="eventMonth">Jan</div>
<div class="eventDate">14</div>
</div>
<div class="eventDescription">
Mural Exhibition
</div>
</div>
<div class="moreLink">
Full Calendar
</div>
</section>
If you want to compare dates then you'll have to somehow massage the various date expressions into all-numeric yyyymmdd format (e.g. 20131029) so that the chronological ordering is equivalent to numerical ordering. For the current date that's a simple global variable:
<xsl:variable name="curDateStr" select="date:date()" />
<xsl:variable name="currentDateNum"
select="concat(substring($curDateStr, 1, 4),
substring($curDateStr, 6, 2),
substring($curDateStr, 9, 2))" />
and to parse the pubDate values I'd use a named template that's the reverse of your current format-month
<xsl:template name="parse-date">
<xsl:param name="dateStr" />
<xsl:value-of select="substring($dateStr, 12, 4)" /><!-- year -->
<xsl:variable name="month" select="substring($dateStr, 8, 3)" />
<xsl:choose>
<xsl:when test="$month = 'Jan'">01</xsl:when>
<xsl:when test="$month = 'Feb'">02</xsl:when>
<!-- etc. -->
</xsl:choose>
<xsl:value-of select="substring($dateStr, 5, 2)" /><!-- day -->
</xsl:template>
Now the main logic can be implemented using a tail-recursive template which is the nearest you can get in XSLT to a "while" loop:
<xsl:template match="item">
<xsl:param name="numItems" select="3" />
<xsl:if test="$numItems > 0"><!-- stop if we hit the threshold -->
<xsl:variable name="itemDate">
<xsl:call-template name="parse-date">
<xsl:with-param name="dateStr" select="pubDate" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$itemDate > $currentDateNum">
<!-- do what you need to do to produce output for this item -->
<!-- ..... -->
<xsl:apply-templates select="following-sibling::item[1]">
<!-- we processed this item, so decrement $numItems -->
<xsl:with-param name="numItems" select="$numItems - 1" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="following-sibling::item[1]">
<!-- we ignored this item, so don't decrement $numItems -->
<xsl:with-param name="numItems" select="$numItems" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
<xsl:if>
</xsl:template>
and then in the channel template you start this "loop" by applying templates to the first item only
<xsl:template match="channel">
<xsl:apply-templates select="item[1]" />
</xsl:template>
The item template will then keep processing siblings until either it runs out of item elements completely, or it has processed 3 items that meet the date criteria.
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.
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>