String comparison in XSLT - xslt

When I call this template I get the following results.
155IT Matches 155OO
155OO Matches 155OO
155PP
The XML I am processing does have three rows and those are the values, but why is the test returning true for the first two and false for the last one? How should I be doing the string comparison?
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template name="ProofOfConcept">
<xsl:param name="Lines"/>
<xsl:param name="MainDeliveryCode"/>
<xsl:choose>
<xsl:when test="$Lines">
<xsl:variable name="CurrentDeliveryCode" select="$Lines/DLVYLOCCD"/>
<p>
<xsl:choose>
<xsl:when test=" $MainDeliveryCode = $CurrentDeliveryCode">
<xsl:value-of select="$CurrentDeliveryCode"/> Matches <xsl:value-of select="$MainDeliveryCode"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$Lines"/> Fails <xsl:value-of select="$MainDeliveryCode"/>
</xsl:otherwise>
</xsl:choose>
</p>
<xsl:call-template name="ProofOfConcept">
<xsl:with-param name="Lines" select="$Lines[position() > 1]"/>
<xsl:with-param name="MainDeliveryCode" select="$MainDeliveryCode"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/">
<html>
<head>
<title></title>
</head>
<body>
<xsl:call-template name="ProofOfConcept">
<xsl:with-param name="Lines" select="data/Lines/LINE"/>
<xsl:with-param name="MainDeliveryCode" select="data/header/DLVYLOCCD"/>
</xsl:call-template>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Sample data
<?xml version="1.0"
encoding="ISO-8859-1"
standalone="yes"?> <data>
<header><DLVYLOCCD>155OO</DLVYLOCCD>
</header> <Lines>
<LINE><DLVYLOCCD>155IT</DLVYLOCCD></LINE>
<LINE><DLVYLOCCD>155OO</DLVYLOCCD></LINE>
<LINE><DLVYLOCCD>155PP</DLVYLOCCD></LINE>
</Lines> </data>
Thanks for any advice.

Here is a less painful version of your XSLT:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="data">
<html>
<head>
<title></title>
</head>
<body>
<!-- this selects the matching LINE node(s), or nothing at all -->
<xsl:apply-templates select="
Lines/LINE[DLVYLOCCD = /data/header/DLVYLOCCD]
" />
</body>
</html>
</xsl:template>
<xsl:template match="LINE">
<p>
<!-- for the sake of the example, just output a copy -->
<xsl:copy-of select="." />
</p>
</xsl:template>
</xsl:stylesheet>
gives (formatted result):
<?xml version="1.0" encoding="utf-8"?>
<html>
<head>
<title></title>
</head>
<body>
<p>
<LINE><DLVYLOCCD>155OO</DLVYLOCCD></LINE>
</p>
</body>
</html>

There are a few things wrong with your implementation. Most important, the expression:
<xsl:variable name="CurrentDeliveryCode" select="$Lines/DLVYLOCCD"/>
returns a node-set consisting of all the DLVYLOCCD elements, not just the current one as you seem to assume. Also, you shouldn't be using recursion to iterate. Use <xsl:for-each> instead, in which case you will process the items one at a time.

I figured it out.
I need to change my test to
<xsl:when test="contains($MainDeliveryCode, $CurrentDeliveryCode" >
That solved the problem.
http://www.zvon.org/xxl/XSLTreference/Output/function_contains.html is the documentation for the function.

Related

XSLT/XPATH : process XHTML files to convert delimited text portions into new <SPAN> class

I got a bunch of files testX.xhtml that are edited in a browser using contenteditable=true. The purpose of the edit is to delimit portions of text with two identical characters like the underscore character in this xhtml file :
{xhtml source file} :
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style xmlns:xhtml="http://www.w3.org/1999/xhtml" type="text/css" xml:space="preserve"/>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
<title>title XHTML</title>
</head>
<body>
<span class="ok">_blablabla blebleble_ bliblibli</span>
<p class="ko">blablabla _blebleble bliblibli <em class="em">one em tag</em> blablabla blebleble._</p>
</body>
</html>
The edited file is saved and then processed by the following xslt in order to have the tagged portion embedded in a new span class named my_span for further treatment :
{xslt file} :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xpath-default-namespace="http://www.w3.org/1999/xhtml"
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output method="xhtml" version="1.0" encoding="UTF-8" indent="yes" standalone="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:for-each select="collection('?select=test*.xhtml')">
<xsl:variable name="path_to_span">
<xsl:value-of select="iri-to-uri(replace(document-uri(current()), '.xhtml', '.span.xhtml'))"/>
</xsl:variable>
<xsl:result-document indent="yes" method="xhtml" href="{$path_to_span}">
<xsl:apply-templates/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<xsl:template match="//text()">
<xsl:analyze-string select="." regex="(.*?)_(.*?)_">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
<span class="my_span">
<xsl:value-of select="regex-group(2)"/>
</span>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
producing the following :
{produced xhtml file} :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style xmlns:xhtml="http://www.w3.org/1999/xhtml" type="text/css" xml:space="preserve"></style>
<title>title XHTML</title>
</head>
<body>
<span class="ok"><span class="my_span">blablabla blebleble</span> bliblibli</span>
<p class="ko">blablabla _blebleble bliblibli <em class="em">one em tag</em> blablabla blebleble._</p>
</body>
</html>
Unfortunately, I figured out that some p tags contain em or i or similar tags that are not handled by my XSLT.
I would like to be able to produce this xhtml :
{expected xhtml file} :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style xmlns:xhtml="http://www.w3.org/1999/xhtml" type="text/css" xml:space="preserve"></style>
<title>title XHTML</title>
</head>
<body>
<span class="ok"><span class="my_span">blablabla blebleble</span> bliblibli</span>
<p class="ko">blablabla
<span class="my_span">blebleble bliblibli </span>
<em class="em"><span class="my_span">one em tag</span></em>
<span class="my_span">blablabla blebleble.</span>
</p>
</body>
</html>
I simplified the xhtml source file to one em tag not handled by my XSLT but there may be many combination of similar tag in one p tag.
In my expected xhtml file, I located the added span inside the em but swapping them would work too.
How to achieve this in XSLT ?
Thanks for help.
I tried to convert the _ character into a processing instruction <?marker?> in one transformation step, then in a second pair such <?marker?>s into <?open?>/<?close?> pairs to finally use a recursive function to group any such pairs based on for-each-group group-starting-with="processing-instruction('open') with a nested for-each-group group-ending-with="processing-instruction('close')":
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 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"
xpath-default-namespace="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="wrap-class" as="xs:string">my_class</xsl:param>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="body">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:variable name="marked-content">
<xsl:apply-templates mode="analyze"/>
</xsl:variable>
<xsl:variable name="paired-content">
<xsl:apply-templates select="$marked-content/node()" mode="pair-markers"/>
</xsl:variable>
<xsl:apply-templates select="$paired-content/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[processing-instruction('open')]">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:sequence select="mf:group(node())"/>
</xsl:copy>
</xsl:template>
<xsl:mode name="analyze" on-no-match="shallow-copy"/>
<xsl:template mode="analyze" match="text()">
<xsl:apply-templates select="analyze-string(., '_')" mode="mark"/>
</xsl:template>
<xsl:template mode="mark" match="fn:*">
<xsl:apply-templates mode="#current"/>
</xsl:template>
<xsl:template mode="mark" match="fn:match">
<xsl:processing-instruction name="marker"/>
</xsl:template>
<xsl:mode name="pair-markers" on-no-match="shallow-copy"/>
<xsl:template mode="pair-markers" match="processing-instruction('marker')">
<xsl:variable name="pos" as="xs:integer">
<xsl:number/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$pos mod 2 = 1">
<xsl:processing-instruction name="open"/>
</xsl:when>
<xsl:otherwise>
<xsl:processing-instruction name="close"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:function name="mf:group">
<xsl:param name="nodes" as="node()*"/>
<xsl:for-each-group select="$nodes" group-starting-with="processing-instruction('open')">
<xsl:choose>
<xsl:when test="self::processing-instruction('open')">
<xsl:for-each-group select="tail(current-group())" group-ending-with="processing-instruction('close')">
<xsl:choose>
<xsl:when test="position() = 1">
<span class="{$wrap-class}">
<xsl:sequence select="mf:group(current-group()[position() ne last()])"/>
</span>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/nb9PtDX

How to group elements based on their siblings using XSLT

I am trying to group several elements based on a starting and ending attribute of their surrounding siblings.
Sample XML:
<list>
<item>One</item>
<item class="start">Two</item>
<item>Three</item>
<item class="end">Four</item>
<item>Five</item>
<item class="start">Six</item>
<item class="end">Seven</item>
<item>Eight</item>
</list>
Desired Result:
<body>
<p>One</p>
<div>
<p>Two</p>
<p>Three</p>
<p>Four</p>
</div>
<p>Five</p>
<div>
<p>Six</p>
<p>Seven</p>
</div>
<p>Eight</p>
</body>
I come close to the desired results with the following XSLT. However, the following-sibling match doesn't stop after it reaches the ending attribute. Also, the standard matching repeats the elements that were already output from the following-sibling match.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="list">
<body>
<xsl:apply-templates />
</body>
</xsl:template>
<xsl:template match="item">
<p>
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="item[#class='start']">
<div>
<p><xsl:apply-templates /></p>
<xsl:apply-templates select="following-sibling::*[not(preceding-sibling::*[1][#class='end'])]" />
</div>
</xsl:template>
</xsl:transform>
Since you're using XSLT 2.0, why don't you take advantage of it:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/list">
<body>
<xsl:for-each-group select="item" group-starting-with="item[#class='start']">
<xsl:for-each-group select="current-group()" group-ending-with="item[#class='end']">
<xsl:choose>
<xsl:when test="count(current-group()) gt 1">
<div>
<xsl:apply-templates select="current-group()" />
</div>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:for-each-group>
</body>
</xsl:template>
<xsl:template match="item">
<p>
<xsl:value-of select="."/>
</p>
</xsl:template>
</xsl:stylesheet>

output for all nodes in the tree

I'm very new to XSL and I want to print out all element nodes by name in a tree structure. So that:
<root>
<childX>
<childY1/>
<childY2/>
</childX>
<childX2/>
</root>
will yield:
root
+--childX
+--childY1
+--childY2
+--childX2
I tried some loops, but probably need recursion....
what I have so far:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="root" match="/">
<html>
<xsl:for-each select="*">
<xsl:value-of select="local-name()"/><br/>
+-- <xsl:for-each select="*">
<xsl:value-of select="local-name()"/><br/>
</xsl:for-each>
</html>
</xsl:template>
would be awesome if you could gimme some hints.
thanks!
Recursion is done using apply-templates, I am not sure it is a good idea to output HTML and then try to construct a tree structure as plain text (creating a nested list in HTML seems more appropriate) but here you go:
<xsl:template match="/">
<html>
<head>
<title>Example</title>
</head>
<body>
<pre>
<xsl:apply-templates/>
</pre>
</body>
</html>
</xsl:template>
<xsl:template match="*">
<xsl:param name="indent" select="'--'"/>
<xsl:value-of select="concat('+', $indent, ' ', local-name())"/>
<br/>
<xsl:apply-templates select="*">
<xsl:with-param name="indent" select="concat('--', $indent)"/>
</xsl:apply-templates>
</xsl:template>

Passing tags in XSLT templates

I'm just starting to learn XSLT, and everything was working fine, until I tried to centralize the formatting.
This is my problem:
XML
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<document>
<code>code</code>
<code>2<exp>3</exp></code>
<text>
This is a <special>special</special> word. 2<exp>3</exp>
</text>
</document>
XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" doctype-public="-//W3C//DTD XHTML 1.1//EN" encoding="utf-8"/>
<xsl:template name="times">·</xsl:template>
<xsl:template name="pow">
<xsl:param name="exponent"/>
<xsl:element name="sup"><xsl:value-of select="$exponent"/></xsl:element>
</xsl:template>
<xsl:template match="exp">
<xsl:call-template name="times"/>
<xsl:text>10</xsl:text>
<xsl:call-template name="pow">
<xsl:with-param name="exponent"><xsl:apply-templates/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template name="codeword">
<xsl:param name="word"/>
<xsl:element name="tt">
<xsl:value-of select="$word"/>
</xsl:element>
</xsl:template>
<xsl:template match="special">
<xsl:call-template name="codeword">
<xsl:with-param name="word"><xsl:apply-templates/></xsl:with-param>
</xsl:call-template>
</xsl:template>
<xsl:template match="document">
<xsl:element name="html">
<xsl:attribute name="xmlns">http://www.w3.org/1999/xhtml</xsl:attribute>
<xsl:element name="head">
<xsl:element name="title"><xsl:text>Title</xsl:text></xsl:element>
</xsl:element>
<xsl:element name="body">
<xsl:apply-templates select="code"/>
<xsl:apply-templates select="text"/>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="code">
<xsl:element name="div">
<xsl:text>(</xsl:text>
<xsl:call-template name="codeword">
<xsl:with-param name="word"><xsl:apply-templates/></xsl:with-param>
</xsl:call-template>
<xsl:text>)</xsl:text>
</xsl:element>
</xsl:template>
<xsl:template match="text">
<xsl:element name="p">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
XHTML (with xsltproc)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Title</title>
</head>
<body>
<div>(<tt>code</tt>)</div>
<div>(<tt>2·103</tt>)</div>
<p>
This is a <tt>special</tt> word. 2·10<sup>3</sup>
</p>
</body>
</html>
So, I'm trying to convert both <code> and <special> tags in the source XML into <tt> in XHTML. But if when I add further tags in the content (like <sup> in this case, through the "exp" and "pow" templates), they are dropped on adding the <tt> (as in the <tt>2·103</tt> line, which should be <tt>2·10<sup>3</sup></tt>).
What am I doing wrong?
As usual, I find the answer shortly after I ask the question (and I had spent some time before trying to find an answer). The answer is here, I have to use copy-of instead of value-of when using the parameters.

Empty/blank namespace declarations being generated within result-document

I have written a package for converting XMLs to ePubs. Everything works fine, except some cases, where blank namespace (xmlns="") nodes are being written to the result-documents. Prior to transformation, I prepared temporary variables for holding main-segments(i.e., meta, body etc.) and finally copied the nodes(using xsl:copy-of[#copy-namespaces='no'] instruction) to result-document. I also have used #exclude-result-prefixes='ns_list_sep_by_space' within xsl:transform element and still not able to get desired result.
oXygen IDE shows a message in pop-up saying:
When using xsl:copy-of the new elements will also have namespace nodes copied from the original element node, unless they are excluded by specifying copy-namespaces="no". If this attribute is omitted, or takes the value yes, then all the namespace nodes of the original element are copied to the new element. If it takes the value no, then none of the namespace nodes are copied: however, namespace nodes will still be created in the result tree as required by the namespace fixup process.
Here is some more details of my problem:
Main stylesheet:
main.xsl:main caller
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:cylian="local-ns-for-extension-functions"
exclude-result-prefixes="xs xd cylian"
version="2.0">
<xsl:import href="modules/core.xsl"/>
<xsl:variable name="base" select="base-uri()" as="xs:anyURI"/>
<xsl:template match="/">
<xsl:call-template name="procA"/>
</xsl:template>
</xsl:transform>
Main stylesheet:
core.xsl: core processing unit
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:cylian="local-ns-for-extension-functions"
exclude-result-prefixes="xs xd cylian"
version="2.0">
<xsl:import href="sub1.xsl"/>
<xsl:import href="sub2.xsl"/>
<!--and more-->
<!-- variable to hold intermediate results for stage1 -->
<xsl:variable name="stage1">
<cylianz>
<xsl:copy-of select="$a" copy-namespaces="no"/>
<xsl:copy-of select="$b" copy-namespaces="no"/>
<!--and more-->
</cylianz>
</xsl:variable>
<!-- variable to hold intermediate results for stage2 -->
<xsl:variable name="stage2">
<cylianz>
<xsl:for-each select="$stage1//cylian">
<xsl:sort select="#pos"/>
<xsl:sequence select="."/>
</xsl:for-each>
</cylianz>
</xsl:variable>
<xsl:template name="procA">
<xsl:for-each select="$stage2//cylian">
<xsl:result-document href="{concat($outdir,#href)}" format="general">
<xsl:call-template name="procB">
<xsl:with-param name="context" select="."/>
<xsl:with-param name="title">
<xsl:value-of select="$book_title"/>
</xsl:with-param>
</xsl:call-template>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<xsl:template name="procB">
<xsl:param name="context"/>
<xsl:param name="title"/>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<xsl:call-template name="header">
<xsl:with-param name="title" select="$title"/>
</xsl:call-template>
</head>
<body>
<div id="root">
<xsl:apply-templates select="."/>
</div>
</body>
</html>
</xsl:template>
<!--
1/ other rules are shortened for clarity
2/ declaration «xmlns:cylian='local-ns-for-extension-functions'» has to retain, some parts of transformation uses some extension functions from that namespace
-->
</xsl:transform>
and here's the output:
a.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta xmlns="" http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title xmlns="">BookTitle</title>
<!--
2012.04.16 - 18:27:36 [XSLT processor: SAXON 9.1.0.5 from Saxonica]
-->
<link xmlns="" href="isbn.css" type="text/css" rel="stylesheet"/>
</head>
<body>
<div id="root">
<div xmlns="" id="a1">
<!--...-->
</div>
</div>
</body>
</html>
I hope it would be easier to understand what's the problem is going on. All suggestions are welcome. Thanks in advance.
Well we need to see your code to be sure but I suspect you have e.g.
<xsl:template match="/">
<foo xmlns="http://example.com/ns">
<xsl:apply-templates/>
</foo>
</xsl:template>
<xsl:template match="whatever">
<bar/>
</xsl:template>
and then you get
<foo xmlns="http://example.com/ns">
<bar xmlns=""/>
</foo>
while you want
<foo xmlns="http://example.com/ns">
<bar/>
</foo>
To fix that make sure you move the default namespace declaration on the xsl:stylesheet element with e.g.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://example.com/ns">
version="1.0">
<xsl:template match="/">
<foo>
<xsl:apply-templates/>
</foo>
</xsl:template>
<xsl:template match="whatever">
<bar/>
</xsl:template>
</xsl:stylesheet>
that way it applies to all result elements created in different templates.
[edit]
Based on the samples you have provided now I think my suggestion is right, only with several files you need to make sure that all stylesheet modules you have put xmlns="http://www.w3.org/1999/xhtml" on the xsl:stylesheet respectively xsl:transform elements so that all result elements end up in the XHTML namespace.
[second edit]
I think you want
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:cylian="local-ns-for-extension-functions"
exclude-result-prefixes="xs xd cylian"
version="2.0">
<xsl:import href="sub1.xsl"/>
<xsl:import href="sub2.xsl"/>
<!--and more-->
<!-- variable to hold intermediate results for stage1 -->
<xsl:variable name="stage1" xmlns="">
<cylianz>
<xsl:copy-of select="$a" copy-namespaces="no"/>
<xsl:copy-of select="$b" copy-namespaces="no"/>
<!--and more-->
</cylianz>
</xsl:variable>
<!-- variable to hold intermediate results for stage2 -->
<xsl:variable name="stage2" xmlns="">
<cylianz>
<xsl:for-each select="$stage1//cylian">
<xsl:sort select="#pos"/>
<xsl:sequence select="."/>
</xsl:for-each>
</cylianz>
</xsl:variable>
<xsl:template name="procA">
<xsl:for-each select="$stage2//cylian">
<xsl:result-document href="{concat($outdir,#href)}" format="general">
<xsl:call-template name="procB">
<xsl:with-param name="context" select="."/>
<xsl:with-param name="title">
<xsl:value-of select="$book_title"/>
</xsl:with-param>
</xsl:call-template>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<xsl:template name="procB">
<xsl:param name="context"/>
<xsl:param name="title"/>
<html >
<head>
<xsl:call-template name="header">
<xsl:with-param name="title" select="$title"/>
</xsl:call-template>
</head>
<body>
<div id="root">
<xsl:apply-templates select="."/>
</div>
</body>
</html>
</xsl:template>
</xsl:transform>
And then if you have any additional modules supposed to produce XHTML elements make sure you put xmlns="http://www.w3.org/1999/xhtml" on the root element of the module or if you need to create elements in other namespaces as well then on any template supposed to output XHTML.
There are two kinds of "unwanted" namespace declarations that might appear in your output: declarations that are unwanted because they are redundant noise (they declare namespace prefixes that aren't used), and declarations that are unwanted because they put the elements in a different namespace from the one intended.
In the first case, XSLT provides features such as exclude-result-prefixes and copy-namespaces='no' to get rid of the noise.
In the second case (which is where I think you are), the namespace declarations are a symptom of the fact that the stylesheet author created the elements in the wrong namespace in the first place, and the solution is to look at the code that created the elements, and fix it. For example you might have written a literal result element <foo> that creates an element in no namespace, when you intended <foo xmlns="something"/> to create it in some other namespace.
Let's have this XML document:
<x:t xmlns:x="some:x">
<a/>
<b/>
</x:t>
Here is code that is probably similar to yours:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<t xmlns="some:x">
<xsl:copy-of select="*" copy-namespaces="no"/>
</t>
</xsl:template>
</xsl:stylesheet>
and it produces this unwanted result:
<t xmlns="some:x">
<a xmlns=""/>
<b xmlns=""/>
</t>
Why is this result produced?
Because you are using <xsl:copy-of> the nodes are copied "as-is", so elements don't change the namespace they are in. The attribute copy-namespaces="no" only specifies that the namespace nodes belonging to this element will be skipped from copying -- not that the element will change its own namespace.
Solution:
When we want to change the namespace an element is in (in this case from "no namespace" to "some:x", we shouldn't copy this element node.
Instead we must create a new element from this one, and specify the new namespace in which the new element should be:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<t xmlns="some:x">
<xsl:apply-templates select="*"/>
</t>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}" namespace="some:x">
<xsl:apply-templates select="node() | #*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the same XML document (above), the wanted, correct result is produced:
<t xmlns="some:x">
<a/>
<b/>
</t>