This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Illustrations re: Namespace node processing (long)
- To: XSL List <xsl-list at mulberrytech dot com>
- Subject: Illustrations re: Namespace node processing (long)
- From: "G. Ken Holman" <gkholman at CraneSoftwrights dot com>
- Date: Wed, 08 Mar 2000 20:32:15 -0800
- Reply-To: xsl-list at mulberrytech dot com
(please be careful if responding to this note to *not* copy the entire
contents into your reply unnecessarily ... thanks!)
Looking back over the messages today about the confusion of namespace
declarations, I decided to look at all aspects of the situation instead of
just embedded documentation as I had earlier.
According to the XSLT 1.0 Recommendation,
"The designation of a namespace as an excluded namespace is
effective within the subtree of the stylesheet rooted at the
element bearing the exclude-result-prefixes or
xsl:exclude-result-prefixes attribute"
.... which is to say that the attribute has *no* relation to the namespaces
used in the source node tree.
So, my book correctly addresses the issue about having namespaces in the
*stylesheet* ... yet the confusion today was about namespaces in the source.
I've written the following to illustrate through separate short examples
what may have been going on with the appearance of namespace declarations
in the result that possibly caused confusion.
First, here are the sources of all of the files I'm using down below:
(1) - an XML source file without namespaces
T:\ftemp>type test.xml
<?xml version="1.0"?>
<doc>
<para>First para</para>
<para>Second para</para>
</doc>
(2) - an XML source file with namespaces
T:\ftemp>type testns.xml
<?xml version="1.0"?>
<doc xmlns:ken="ken.com">
<para>First para</para>
<para>Second para</para>
</doc>
(3) - an XSLT stylesheet without namespaces
T:\ftemp>type test.xsl
<?xml version="1.0"?><!--filename.xsl-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/"> <!--root rule-->
<result>
<xsl:copy-of select="/doc/para"/>
</result>
</xsl:template>
</xsl:stylesheet>
(4) - an XSLT stylesheet with a documentation namespace
T:\ftemp>type testns.xsl
<?xml version="1.0"?><!--filename.xsl-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:ken="ken.com">
<xsl:output method="xml"/>
<ken:hello>test</ken:hello>
<xsl:template match="/"> <!--root rule-->
<result>
<xsl:copy-of select="/doc/para"/>
</result>
</xsl:template>
</xsl:stylesheet>
(5) - an XSLT stylesheet with an exclude on a literal result element
T:\ftemp>type testnsex.xsl
<?xml version="1.0"?><!--filename.xsl-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:ken="ken.com">
<xsl:output method="xml"/>
<ken:hello>test</ken:hello>
<xsl:template match="/"> <!--root rule-->
<result xsl:exclude-result-prefixes="ken">
<xsl:copy-of select="/doc/para"/>
</result>
</xsl:template>
</xsl:stylesheet>
(6) - an XSLT stylesheet with an exclude on the document element of the
stylesheet
T:\ftemp>type testnsde.xsl
<?xml version="1.0"?><!--filename.xsl-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:ken="ken.com"
exclude-result-prefixes="ken">
<xsl:output method="xml"/>
<ken:hello>test</ken:hello>
<xsl:template match="/"> <!--root rule-->
<result>
<xsl:copy-of select="/doc/para"/>
</result>
</xsl:template>
</xsl:stylesheet>
(7) - an XSLT stylesheet with an exclude on the document element of the
stylesheet and using template rules instead of copy-of:
T:\ftemp>type testnstr.xsl
<?xml version="1.0"?><!--filename.xsl-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:ken="ken.com"
exclude-result-prefixes="ken">
<xsl:output method="xml"/>
<ken:hello>test</ken:hello>
<xsl:template match="/"> <!--root rule-->
<result>
<xsl:apply-templates select="/doc/para"/>
</result>
</xsl:template>
<xsl:template match="para">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
</xsl:stylesheet>
(8) - an XSLT stylesheet using template rules without any
exclude-result-prefixes=
<?xml version="1.0"?><!--filename.xsl-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/"> <!--root rule-->
<result>
<xsl:apply-templates select="/doc/para"/>
</result>
</xsl:template>
<xsl:template match="para">
<para>
<xsl:apply-templates/>
</para>
</xsl:template>
</xsl:stylesheet>
=============8<----------------------
(T1) - Okay, so first no namespaces to show the desired result:
T:\ftemp>xt test.xml test.xsl
<?xml version="1.0" encoding="utf-8"?>
<result><para>First para</para><para>Second para</para></result>
(T2) - Introducing the documentation namespace without an exclude produces
a result:
T:\ftemp>xt test.xml testns.xsl
<?xml version="1.0" encoding="utf-8"?>
<result xmlns:ken="ken.com"><para>First para</para><para>Second
para</para></result>
.... where the processor emits a contingent declaration *just in case*.
(T3) - Using an exclude-result-prefixes= on the stylesheet document element
filters it out (this is as far as I have gone in my book to date, focusing
on the use of namespaces in embedded documentation):
T:\ftemp>xt test.xml testnsde.xsl
<?xml version="1.0" encoding="utf-8"?>
<result><para>First para</para><para>Second para</para></result>
(T4) - Using an exclude-result-prefixex= on the literal result element
isn't recognized for XT (an http://www.jclark.com/xml/xt.html documented
limitation, so we shouldn't be expecting it, but that might be the source
of some confusion), but does for Saxon:
T:\ftemp>xt test.xml testnsex.xsl
<?xml version="1.0" encoding="utf-8"?>
<result xmlns:ken="ken.com"><para>First para</para><para>Second
para</para></result>
T:\ftemp>saxon test.xml testnsex.xsl
<?xml version="1.0" encoding="utf-8" ?><result><para>First
para</para><para>Second para</para></result>
(T5) - Now, the source file with the namespace declaration on the document
element is processed with both types of exclude-result-prefixes= and while
the document element of the result doesn't have the namespace declaration,
the descendants do:
T:\ftemp>saxon testns.xml testnsex.xsl
<?xml version="1.0" encoding="utf-8" ?><result><para
xmlns:ken="ken.com">First para</para><para xmlns:ken="ken.com">Second
para</para></result>
T:\ftemp>xt testns.xml testnsde.xsl
<?xml version="1.0" encoding="utf-8"?>
<result><para xmlns:ken="ken.com">First para</para><para
xmlns:ken="ken.com">Second para</para></result>
T:\ftemp>saxon testns.xml testnsde.xsl
<?xml version="1.0" encoding="utf-8" ?><result><para
xmlns:ken="ken.com">First para</para><para xmlns:ken="ken.com">Second
para</para></result>
At first one might not expect the above behaviour in Test5 ... if none of
my result tree descendents utilize the namespace, then why would each one
get a namespace declaration? It has nothing to do with the
exclude-result-prefixes= because the scope of that attribute is in the
stylesheet.
It is because of the use of <xsl:copy-of> and the first sentence of section
5.4 of the XPath 1.0 Recommendation:
"Each element has an associated set of namespace
nodes, one for each distinct namespace prefix that
is in scope for the element"
Thus, the <para> elements of the source node tree each have an invisible
namespace node for the "ken" namespace that we cannot see.
Because I used <xsl:copy-of>, I copied *all* of the nodes of the source
tree (including the invisible namespace nodes) to the result tree ...
hence, the processor is obliged to put out the namespace declaration for
the namespace nodes found in the result tree.
(T6) - So, to avoid using <xsl:copy-of> I then used the stylesheet that
uses template rules instead:
T:\ftemp>xt testns.xml testnstr.xsl
<?xml version="1.0" encoding="utf-8"?>
<result><para>First para</para><para>Second para</para></result>
.... and sure enough, since my stylesheet isn't adding any namespace nodes
to the result tree, there are no namespace declarations in the result.
(T7) - The last test looks at *not* using exclude-result-prefixes= but
still having namespaces in the source to illustrate there was never any
need for exclude-result-prefixes= to handle source issues:
T:\ftemp>xt testns.xml testtr.xsl
<?xml version="1.0" encoding="utf-8"?>
<result><para>First para</para><para>Second para</para></result>
... and note that since I didn't copy any of the invisible (or visible)
namespace nodes, the end result doesn't need any namespace declarations.
There is the evidence supporting the Recommendations ... and it seems the
processors here obey the rules where they are documented to obey the
rules. Perhaps the key that was missing was the knowledge of the hidden
namespace nodes implied by the scope of ancestral namespace declarations.
I will put all of the above into the next edition of our book, with some of
the sentences fleshed out and perhaps rearranged as I think about the best
way to present it. I don't think I've missed any of the combinations or
the explanations ... if something still isn't said about namespace
processing, please post your question.
I hope this helps.
................ Ken
--
G. Ken Holman mailto:gkholman@CraneSoftwrights.com
Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (Fax:-0995)
Web site: XSL/XML/DSSSL/SGML services, training, libraries, products.
Practical Transformation Using XSLT and XPath ISBN 1-894049-04-7
Next instructor-led training: 2000-05-02,2000-05-11/12,2000-05-15,
- 2000-06-12,2000-06-13,2001-01-27
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list