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.
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:
Here is code that is probably similar to yours:
and it produces this unwanted result:
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 attributecopy-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:
When this transformation is applied on the same XML document (above), the wanted, correct result is produced:
Well we need to see your code to be sure but I suspect you have e.g.
and then you get
while you want
To fix that make sure you move the default namespace declaration on the xsl:stylesheet element with e.g.
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 thexsl:stylesheet
respectivelyxsl:transform
elements so that all result elements end up in the XHTML namespace.[second edit] I think you want
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.