Can this xpath be simplified? - xslt-1.0

I have this code:
<!--Display the name of the brother assigned-->
<xsl:template match="Name | PrayerOpen | PrayerEnd">
<td class="cellName">
<xsl:choose>
<xsl:when test="//MeetingWorkBook/Settings/ForeignGroupMode='1' and (
../#BookmarkId='2' or ../../#BookmarkId='2' or
../../../#BookmarkId='2'or ../../../../#BookmarkId='2' or
../#BookmarkId='4' or ../../#BookmarkId='4' or
../../../#BookmarkId='4' or ../../../../#BookmarkId='4' or
self::PrayerOpen or self::PrayerEnd)">
<em><xsl:value-of select ="//Labels/MainHall"/></em>
</xsl:when>
<xsl:when test="//MeetingWorkBook/Settings/ForeignGroupMode='1' and .='' and self::Name">
<em><xsl:value-of select ="//Labels/MainHall"/></em>
</xsl:when>
<xsl:when test="#Duplicate=1">
<span class="textDuplicate">
<xsl:value-of select="."/>
</span>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
It works fine. I have a series of paths so that I can find the correct node which has the BookmarkId attribute. Can this code be simplified?
Basically, based on the context of the current node I want to walk up the parents until it hits the Meeting node which is the one with the attribute.
Example XML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Workbook-S-140-PublicTalk-WatchtowerStudy-ServiceTalk-FGroup-v2.xsl"?>
<MeetingWorkBook>
<Meeting BookmarkId="0" PageBreak="0" NumberClasses="1" SpecialEvent="0">
<PrayerOpen>Name 1</PrayerOpen>
<TFGW NumberClasses="1">
<TFGWItem>
<Name>Name 2</Name>
</TFGWItem>
<TFGWItem>
<Name>Name 3</Name>
</TFGWItem>
</TFGW>
<AYFM NumberClasses="1">
<Teaching>
<Name>Name 4</Name>
</Teaching>
</AYFM>
<LAC CircuitVisit="0">
<LACItem>
<Name>Name 5</Name>
</LACItem>
<PrayerEnd>Name 6</PrayerEnd>
</LAC>
</Meeting>
</MeetingWorkBook>

Based on the advice in the comments I have ended up using the ancestor call. So my template now looks like this:
<!--Display the name of the brother assigned-->
<xsl:template match="Name | PrayerOpen | PrayerEnd">
<td class="cellName">
<xsl:choose>
<xsl:when test="//MeetingWorkBook/Settings/ForeignGroupMode='1' and (
ancestor::Meeting[#BookmarkId='2'] or
ancestor::Meeting[#BookmarkId='4'] or self::PrayerOpen or self::PrayerEnd)">
<em><xsl:value-of select ="//Labels/MainHall"/></em>
</xsl:when>
<xsl:when test="//MeetingWorkBook/Settings/ForeignGroupMode='1' and .='' and self::Name">
<em><xsl:value-of select ="//Labels/MainHall"/></em>
</xsl:when>
<xsl:when test="#Duplicate=1">
<span class="textDuplicate">
<xsl:value-of select="."/>
</span>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>

Related

I need to start the delem (concept-expected output) after r4 (conbody- expected output), which is not happening

I need to start the delem (concept-expected output) after r4 (conbody- expected output), currently with respect to r4 mapping, conbody is wrapping the concept (delem).
Basically, I want r4 conbody to end before delem (concept) element.
I am stuck, Need help with the solution.
Input xml
<?xml version="1.0" encoding="UTF-8"?>
<specif>
<rtit>Test specif</rtit>
<r3>
<rtit>Test r3</rtit>
<r4>
<rtit>Test r4</rtit>
<p> para Test r4</p>
<delem>
<p>para Test delem</p>
</delem>
<r6>
<rtit>Test r6</rtit>
<p>para Test r6</p>
</r6>
</r4>
</r3>
</specif>
current output
<?xml version="1.0" encoding="UTF-8"?>
<concept>
<title>Test specif</title>
<conbody/>
<concept>
<title>Test r3</title>
<conbody/>
<concept>
<title>Test r4</title>
<conbody>
<p> para Test r4</p>
<concept>
<title></title>
<conbody> <p> para Test delem</p> </conbody>
</concept>
</conbody>
<concept>
<title>Test r6</title>
<conbody> <p> para Test r6</p> </conbody>
</concept>
</concept>
</concept>
</concept>
Expected output
<?xml version="1.0" encoding="UTF-8"?>
<concept>
<title>Test specif</title>
<conbody/>
<concept>
<title>Test r3</title>
<conbody/>
<concept>
<title>Test r4</title>
<conbody><p> para Test r4</p></conbody>
<concept>
<title></title>
<conbody> <p> para Test delem</p> </conbody>
</concept>
<concept>
<title>Test r6</title>
<conbody> <p> para Test r6</p> </conbody>
</concept>
</concept>
</concept>
</concept>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="sb/body/specif"/>
</xsl:template>
<xsl:template match="specif">
<concept>
<xsl:attribute name="xsi:noNamespaceSchemaLocation" select="'techinfo.xsd'"/>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<xsl:apply-templates select="*[matches(local-name(),'r3')]"/>
</concept>
</xsl:template>
<xsl:template match="*[matches(local-name(),'r3')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<conbody>
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</conbody>
<!-- apply recursive -->
<xsl:apply-templates select="*[matches(local-name(),'r4')]"/>
</concept>
</xsl:template>
<xsl:template match="*[matches(local-name(),'r4')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<conbody>
<xsl:choose>
<xsl:when test="child::r5|r6|r7|r8|r9">
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</xsl:when>
<xsl:when test="child::delem">
<xsl:apply-templates select="*[not(starts-with(local-name(),'delem'))]"/>
</xsl:when>
</xsl:choose>
</conbody>
<!-- apply recursive -->
<xsl:choose>
<xsl:when test="child::r5|r6|r7|r8|r9">
<xsl:apply-templates select="*[matches(local-name(),'r[5-9]')]"/>
</xsl:when>
<xsl:when test="child::delem">
<xsl:apply-templates select="delem"/>
</xsl:when>
</xsl:choose>
</concept>
</xsl:template>
<!--tch on all nodes like r1, r2,r4,r5,r6 etc-->
<xsl:template match="*[matches(local-name(),'r[5-9]')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<conbody>
<xsl:choose>
<xsl:when test="*[matches(local-name(),'r[5-9]')]">
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</xsl:when>
<xsl:when test="*[matches(local-name(),'delem')]">
<xsl:apply-templates select="*[not(starts-with(local-name(),'delem'))]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="*[not(starts-with(local-name(),'r'))]"/>
</xsl:otherwise>
</xsl:choose>
</conbody>
<!-- apply recursive -->
<xsl:choose>
<xsl:when test="*[matches(local-name(),'r[5-9]')]">
<xsl:apply-templates select="*[matches(local-name(),'r[5-9]')]"/>
</xsl:when>
<xsl:when test="*[matches(local-name(),'delem')]">
<xsl:apply-templates select="*[matches(local-name(),'delem')]"/>
</xsl:when>
</xsl:choose>
</concept>
</xsl:template>
<xsl:template match="delem">
<xsl:choose>
<xsl:when test="*[matches(local-name(),'r[3-9]')]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<xsl:for-each select="child::subtitle">
<shortdesc>
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</shortdesc>
</xsl:for-each>
<conbody>
<!-- the logic of #id/#group attributes is not clear -->
<xsl:apply-templates select="*[not(starts-with(local-name(),'r')) ]"/>
</conbody>
<!-- apply recursive -->
<xsl:apply-templates select="*[matches(local-name(),'r[3-9]')]"/>
</concept>
</xsl:when>
<xsl:when test="*[not(matches(local-name(),'r[3-9]'))]">
<concept>
<xsl:choose>
<xsl:when test="not(#id)">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id ='')">
<xsl:attribute name="id">
<xsl:value-of select="'concept'"/>
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
</xsl:when>
<xsl:when test="(#id !='')">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:attribute name="xml:lang">
<xsl:value-of select="'en'"/>
</xsl:attribute>
<title>
<xsl:for-each select="child::rtit">
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</xsl:for-each>
</title>
<xsl:for-each select="child::subtitle">
<shortdesc>
<xsl:attribute name="id">
<xsl:value-of select="#id"/>
</xsl:attribute>
<xsl:apply-templates select="node()|#*|text()"/>
</shortdesc>
</xsl:for-each>
<conbody>
<xsl:apply-templates/>
</conbody>
</concept>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="rtit"/>
</xsl:stylesheet>

xslt change writing-mode to FA is metadata language is FA

I'm working in the xsl-file "generate_document_structure.xsl" and a'm not so familiar with this older structure.
My goal in this is to change the writing-mode from lr-tb to rl-tb if the language in the METADATA is FA or AR.
Below a cleaned-up piece of code from the ouputfolder
<?xml version="1.0" encoding="UTF-8"?>
<fctdcl>
<publicationinfo dclselection="SelectedNode">
<props>
<attrblock type="1toN" name="language">
<attrlist>
<attrdesc id="1" name="language"/>
</attrlist>
<attrrec>
<attrval id="1">Default</attrval>
</attrrec>
</attrblock>
</props>
</publicationinfo>
It is a big guess for my how to make the connection to the METADATA if the language is FA. in other words, i'm looking for the wright xpath to the METADATA and select the value of it.
i was thinking in the way like below:
<xsl:variable name="language">
<xsl:value-of select="//*[contains(#class, ' /FCTDocuments/metadata/#language ')]/#content"></xsl:value-of>
</xsl:variable>
<xsl:choose>
<xsl:when test="$language = 'FA'">
<xsl:attribute name="writing-mode">rl-tb</xsl:attribute>
</xsl:when>
</xsl:choose>
I would appreciate it if someone could help me in this
#Toni,
I made some steps with it.
Below my current file.
<xsl:template name="FoT_page-sequence_ContentSequence">
<xsl:choose>
<xsl:when test="not(/FCTDocuments/chapter)">
<fo:page-sequence master-reference="ContentSequence">
<xsl:call-template name="AddHyphenationToSequence"/>
<xsl:call-template name="chapter_header_footer_without_config"/>
<fo:flow flow-name="xsl-region-body" xsl:use-attribute-sets="XSL_Content">
<fo:block id="last-page"/>
</fo:flow>
</fo:page-sequence>
</xsl:when>
<xsl:otherwise>
<xsl:for-each select="/FCTDocuments/chapter">
<fo:page-sequence master-reference="ContentSequence" initial-page-number="auto-odd" writing-mode="rl-tb"> <!---->
<xsl:if test="/FCTDocuments/#RSKM-ProductType = 'MM' ">
<xsl:attribute name="initial-page-number">
<xsl:text>1</xsl:text>
</xsl:attribute>
</xsl:if>
<fo:flow flow-name="xsl-region-body" xsl:use-attribute-sets="XSL_Content">
<xsl:if test="count(preceding-sibling::chapter) = 0">
<xsl:if test="$DEBUG = 'true'">
<!-- write debug informations -->
<xsl:comment>
<xsl:text>DEBUG: Starting Content creation</xsl:text>
</xsl:comment>
</xsl:if>
<fo:block>
<fo:marker marker-class-name="DOCUMENTNAME">
<xsl:value-of select="/FCTDocuments/Cover/CoverTitle"/>
</fo:marker>
<fo:marker marker-class-name="DOCUMENTINFO">
<xsl:value-of select="$DOCUMENTINFO"/>
</fo:marker>
</fo:block>
</xsl:if>
<xsl:apply-templates select="."/>
<xsl:if test="count(following-sibling::chapter) = 0">
<fo:block id="last-page"/>
</xsl:if>
</fo:flow>
</fo:page-sequence>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
As we zoom in at the codepart below i added the attribure "writing-mode" in the fo:page-sequence. And after a test it worked fine, But this must only happend when the language is FA
So no i need to make a choose of if statement like test="/FCTDocuments/#RSKM-Language = 'FA'">
how do I manage that if the lang-attribute is FA
<fo:page-sequence master-reference="ContentSequence" initial-page-number="auto-odd" writing-mode="rl-tb"> <!---->
<xsl:if test="/FCTDocuments/#RSKM-ProductType = 'MM' ">
<xsl:attribute name="initial-page-number">
<xsl:text>1</xsl:text>
</xsl:attribute>
</xsl:if>
You initially said you were looking for the right XPath to select your METADATA/metadata, which is why I was asking to see the language code in your source XML.
I am guessing that this is what you want:
<xsl:if test="/FCTDocuments/#RSKM-Language = 'FA'">
<xsl:attribute name="writing-mode">rl</xsl:attribute>
</xsl:if>
You can then omit the writing-mode property on the fo:page-sequence since the default writing-mode value is lr-tb.

I am trying to get XSL to render an XML attribute with an & tag as &amp

I have an XML tag which has names in it e.g. H&M. The requirement is that it should output as H &amp M. I am unable to achieve this yet.
None of the escape characters, & or & worked for me. Here's what worked:
<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:choose>
<xsl:when test="contains($text, '&')">
<xsl:value-of select="substring-before($text,'&')"/>
<xsl:text disable-output-escaping="yes"><![CDATA[&]]></xsl:text>
<xsl:value-of select="substring-after($text,'&')"/>
</xsl:when>
<xsl:when test="contains($text, '&apos;')">
<xsl:value-of select="substring-before($text,'&apos;')"/>
<xsl:text disable-output-escaping="yes"><![CDATA[&apos;]]></xsl:text>
<xsl:value-of select="substring-after($text,'&apos;')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
And then call template:
<Nm>
<xsl:variable name="suppNm">
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="Payee/Name" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$suppNm" />
</Nm>
If anyone knows a better solution, would be very interested to know. I am a total beginner to XSL.

XSLT1.0 replace multiple occurences of char with <br />

Have the following template that I use with xsl:call-template, but I need to use it to replace a ~ with <br />. I can get it to work with none HTML replacements but not when I try to use <br /> or &NewLine; or
. Any suggestions:
<xsl:template name="replace-substring">
<xsl:param name="original"/>
<xsl:param name="substring"/>
<xsl:param name="replacement" select="''"/>
<xsl:variable name="first">
<xsl:choose>
<xsl:when test="contains($original, $substring)" >
<xsl:value-of select="substring-before($original, $substring)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$original"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="middle">
<xsl:choose>
<xsl:when test="contains($original, $substring)">
<xsl:value-of select="$replacement" />
</xsl:when>
<xsl:otherwise>
<xsl:text></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="last">
<xsl:choose>
<xsl:when test="contains($original, $substring)">
<xsl:choose>
<xsl:when test="contains(substring-after($original, $substring),
$substring)">
<xsl:call-template name="replace-substring">
<xsl:with-param name="original">
<xsl:value-of select="substring-after($original, $substring)"/>
</xsl:with-param>
<xsl:with-param name="substring">
<xsl:value-of select="$substring"/>
</xsl:with-param>
<xsl:with-param name="replacement">
<xsl:value-of select="$replacement"/>
</xsl:with-param>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-after($original, $substring)" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:text></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat($first, $middle, $last)"/>
</xsl:template>
It's hard to tell what's going on with the first, middle, and last variables but you should be able to just use a literal <br/> in your param...
XML
<test>one~two~three</test>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="test">
<xsl:copy>
<xsl:call-template name="replace-char"/>
</xsl:copy>
</xsl:template>
<xsl:template name="replace-char">
<xsl:param name="char" select="'~'"/>
<xsl:param name="replacement"><br/></xsl:param>
<xsl:param name="string" select="."/>
<xsl:variable name="remaining" select="substring-after($string,$char)"/>
<xsl:value-of select="substring-before(concat($string,$char),$char)"/>
<xsl:if test="contains($string,$char)">
<xsl:copy-of select="$replacement"/>
</xsl:if>
<xsl:if test="$remaining">
<xsl:call-template name="replace-char">
<xsl:with-param name="string" select="$remaining"/>
<xsl:with-param name="char" select="$char"/>
<xsl:with-param name="replacement" select="$replacement"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Output
<test>one<br/>two<br/>three</test>

need to replace special characters

Hi I have a part of my xml document as below. In this xsm document I have a special character as “ and &#x201D. I want them to be replaced by “ and ” in my HTML output using XSL.
I am searching for a template or any other alternative method to scan my entire XML document and replace where ever the special characters are found. Right now it is being replaced by some white boxes. Please let me know how do I do it.
<para>
<phrase>2.081</phrase> In creating a vehicle like a restricted purpose company, the British Virgin Islands legislature was clearly concerned that, if such vehicles became widely used, there might be a risk that persons dealing with British Virgin Islands companies generally may have become concerned about the ability of companies to engage in day-to-day transactions. Accordingly, it sought to address these concerns by two slightly different mechanisms. Firstly, all restricted purpose companies were required to include the designation “(SPV) Limited” in their name, to make sure they were readily identifiable (even without reviewing their constitutional documents). Secondly, restricted purpose companies were made subject to licence fees significantly higher than regular companies to limit their use to appropriate cases.</para>
<table frame="all" width="100%">
<title>Comparing restricted purpose companies</title>
<tgroup cols="3">
<colspec colnum="1" colname="col1" colwidth="33%"/>
<colspec colnum="2" colname="col2" colwidth="33%"/>
<colspec colnum="3" colname="col3" colwidth="33%"/>
<thead>
I also want a method to get the number of <colspec> elements below <tgroup cols=""> (attribute cols should be there). There are also <tgroup> elements without the cols attribute.
This is my current XSLT:
<?xml version="1.0" encoding="utf-8"?>
<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:template match="/">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>
<xsl:value-of select="chapter/title"/>
</title>
<link rel="stylesheet" href="er:#css" type="text/css" />
</head>
<body>
<xsl:apply-templates/>
<hr />
<section class="tr_footnotes">
<xsl:apply-templates select="//footnote" mode="footnote"/>
</section>
</body>
</html>
</xsl:template>
<xsl:template match="chapter">
<section>
<div class="chapter">
<a name="BVI-CH-{#num}" />
<xsl:variable name="cnum">
<xsl:choose>
<xsl:when test="starts-with(#num,'0')">
<xsl:value-of select="substring-after(#num,'0')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#num"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable><div class="chapter-title"><span class="chapter-num">
<xsl:value-of select="concat('Chapter ',$cnum,' ')"/>
</span>
<xsl:apply-templates/>
</div></div>
</section>
</xsl:template>
<xsl:template match="chapter/para">
<div class="para align-right">
<span class="format-smallcaps">Para</span>.
</div>
</xsl:template>
<!-- Index templates -->
<xsl:template name="toc" match="chapter/toc">
<div class="toc">
<xsl:call-template name="toc-part"></xsl:call-template>
</div>
</xsl:template>
<xsl:template name="toc-part" match="chapter/toc/toc-part">
<div class="toc-part">
<xsl:call-template name="toc-div"></xsl:call-template>
</div>
</xsl:template>
<xsl:template name="toc-div" match="chapter/toc/toc-part/toc-div">
<table class="toc-div">
<tbody>
<xsl:for-each select="current()/toc-part/toc-div/*">
<xsl:call-template name="toc-item"></xsl:call-template>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
<xsl:template name="toc-item" match="chapter/toc/toc-part/toc-div/toc-item">
<xsl:variable name="tocpg" >
<xsl:value-of select="concat('#P',current()/toc-pg/text())"/>
</xsl:variable>
<xsl:variable name="tocpgtag" select="translate($tocpg,'.', '-')" />
<xsl:variable name="chapternumber">
<!-- Get num attribute of parent node -->
<xsl:value-of select="ancestor::chapter[1]/#num"/>
</xsl:variable>
<xsl:variable name="itemlevel">
<xsl:value-of select="$ThisDocument//ntw:nums[#num=$chapternumber]/#word"></xsl:value-of>
</xsl:variable>
<xsl:variable name="tocitemlevel">
<xsl:value-of select="concat('toc-item-', $itemlevel,'-level')"></xsl:value-of>
</xsl:variable>
<table class="{$tocitemlevel}">
<tbody>
<tr>
<td class="toc-item-num">
<xsl:value-of select="current()/#num"/>
</td>
<td class="toc-title">
<xsl:value-of select="current()/toc-title"/>
</td>
<td class="toc-pg">
<a href="{$tocpgtag}">
<xsl:value-of select="current()/toc-pg"/>
</a>
</td>
</tr>
</tbody>
</table>
</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-',#level)"/>
</xsl:variable>
<xsl:variable name="chapternumber">
<!-- Get num attribute of parent node -->
<xsl:value-of select="ancestor::chapter[1]/#num"/>
</xsl:variable>
<xsl:variable name="sectnum">
<xsl:number level="any" count="section" format="1"/>
</xsl:variable>
<!--Create a string variable by concat string method -->
<xsl:variable name="sectionname">
<xsl:value-of select="concat('CH-',$chapternumber,'-SEC-0', $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"/>
</span>
<xsl:apply-templates/>
</div>
</div>
</xsl:template>
<!--<xsl:template name="para" match="section/para">
<xsl:variable name="count2">
<xsl:value-of select="count[child::node()]"></xsl:value-of>
</xsl:variable>
<xsl:choose>
<xsl:when test="$count2 >=1">
<div class="para">
<span class="phrase">
<xsl:value-of select="current()/phrase"/>
</span>
<xsl:apply-templates/>
</div>
</xsl:when>
<xsl:when test="$count2 < 1">
<span class="phrase">
<xsl:value-of select="current()/phrase"/>
</span>
<xsl:apply-templates mode="nr"/>
</xsl:when>
</xsl:choose>
</xsl:template> -->
<xsl:template name="para" match="section/para">
<xsl:choose>
<xsl:when test="contains()">
<div class="para">
<span class="phrase">
<xsl:value-of select="current()/phrase"/>
</span>
<xsl:apply-templates/>
</div>
</xsl:when>
</xsl:choose>
</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,'%','')}"><colgroup></colgroup>
<xsl:apply-templates/>
</table>
</xsl:template>
<xsl:template name="tbody" match="tgroup/tbody">
<tbody>
<xsl:for-each select="current()/row">
<xsl:call-template name="row"></xsl:call-template>
</xsl:for-each>
</tbody>
</xsl:template>
<xsl:template name="thead" match="tgroup/thead">
<xsl:value-of select="name()"></xsl:value-of>
<xsl:for-each select="current()/row">
<xsl:value-of select="name()"></xsl:value-of>
<tr>
<xsl:for-each select="current()/entry">
<xsl:call-template name="headentry"></xsl:call-template>
</xsl:for-each>
</tr>
</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:call-template>
</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:value-of>
</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()"></xsl:value-of>
</div>
</td>
</xsl:if>
</xsl:when>
<xsl:when test="$count > 1">
<td>
<div class="para">
<!--xsl:value-of select="current()"/-->
<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()"/>
</div>
</th>
</xsl:template>
<!-- Table Templates complete -->
<!--List templates -->
<xsl:template name="orderedlist" match="orderedlist">
<ol class="orderedlist">
<xsl:apply-templates/>
</ol>
</xsl:template>
<xsl:template name="orderitem" match="orderlist/item">
<li class="item">
<xsl:apply-templates/>
</li>
</xsl:template>
<xsl:template name="orderitempara" match="item/para">
<xsl:variable name="itemnumber">
<xsl:value-of select="parent::item[1]/#num"/>
</xsl:variable><li class="item">
<div class="para">
<span class="item-num">
<xsl:value-of select="parent::item[1]/#num"/>
</span>
<xsl:apply-templates></xsl:apply-templates>
</div></li>
</xsl:template>
<!--List templates Complete -->
<!-- Paragraph templates Complete -->
<!-- Footnote Templates-->
<xsl:template match="footnote"><sup>
<a>
<xsl:attribute name="name"><xsl:text>footnoteref</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="href"><xsl:text>#footnote</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="class">
<xsl:text>tr_ftn</xsl:text><xsl:number level="any" count="footnote" format="1"/>
</xsl:attribute>
<xsl:number level="any" count="footnote" format="1"/>
</a></sup>
</xsl:template>
<xsl:template match="footnote" mode="footnote"><sup>
<li style="list-style-type:none;indent:0">
<a>
<xsl:attribute name="name"><xsl:text>footnote</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="href"><xsl:text>#footnoteref</xsl:text><xsl:number level="any" count="footnote" format="1"/></xsl:attribute>
<xsl:attribute name="class">
<xsl:text>tr_ftn</xsl:text><xsl:number level="any" count="footnote" format="1"/>
</xsl:attribute>
<xsl:number level="any" count="footnote" format="1"/>
</a>
<xsl:text> </xsl:text>
<xsl:apply-templates/>
</li></sup>
</xsl:template>
<xsl:template match="footnote/para/uri">
<a>
</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:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Namespace ntw-->
<ntw:nums num="01" word="first"></ntw:nums>
<ntw:nums num="02" word="second"></ntw:nums>
<ntw:nums num="03" word="third"></ntw:nums>
<ntw:nums num="04" word="forth"></ntw:nums>
<ntw:nums num="05" word="fifth"></ntw:nums>
<ntw:nums num="06" word="sixth"></ntw:nums>
<ntw:nums num="07" word="seventh"></ntw:nums>
<ntw:nums num="08" word="eighth"></ntw:nums>
<ntw:nums num="09" word="nighth"></ntw:nums>
<ntw:nums num="10" word="tenth"></ntw:nums>
<!-- Namespace ntw ends -->
</xsl:stylesheet>
Thanks
As I am not exactly sure on which place you want to count al the <colspec> elements here an explanation of count():
You can use count(node-set) (replace node-set with your desired node-set to count) to count all the nodes from where you start it. For example:
Count all <colspec> elements in XML:
<xsl:value-of select="count(//colspec)" />
Count all <colspec> elements from the path you are now:
<xsl:value-of select="count(colspec)" />
Count all <colspec> elements from the path you are now below element <tgroup>:
<xsl:value-of select="count(tgroup/colspec)" />
Your question about the " is not clear to me. Please keep in mind that HTML and XML have some special characters which you never can display as is in source code. See next:
HTML special characters: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Character_entity_references_in_HTML
XML special characters: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML
Hope it helps you out!