Re: [xsl] Q: XSLT 1.0 output of namespace

Subject: Re: [xsl] Q: XSLT 1.0 output of namespace
From: Hermann Stamm-Wilbrandt <STAMMW@xxxxxxxxxx>
Date: Tue, 17 Aug 2010 16:26:11 +0200
Michael,

> It might be simpler, but it's wrong. Firstly, the expression
> attribute::*[name()] is rather pointless: it selects all attribute that
> have a name, and all of them do.
I did not realize that because the testcases worked.

> While namespace::*[name()] selects all
> namespaces except the default namespace, so your test will fail for that
> one.
You are absolutely right.

Your counting technique works on the nodes which is correct and not on
string values which is incorrect.

is-no-attribute-and-no-namespace():
                "count(. | ../attribute::* | ../namespace::*) !=
                 count(../attribute::* | ../namespace::*)"
is-attribute(): "count(. | ../@*) = count(../@*)"
is-namespace(): "count(. | ../namespace::*) = count(../namespace::*)"

Thank you for that technique!


This is the diff for the tool, I updated dynxp.xsl [1] and xpath++ tool
[2].

$ diff -u dynxp.xsl.posted dynxp.xsl
--- dynxp.xsl.posted    2010-08-17 15:27:10.000000000 +0200
+++ dynxp.xsl   2010-08-17 15:59:33.000000000 +0200
@@ -26,12 +26,12 @@
         <xsl:copy-of select="."/>
       </xsl:when>
       <xsl:when
-        test="name() and
-              not(. = ../attribute::*[name()] | ../namespace::*[name()])">
+        test="count(. | ../attribute::* | ../namespace::*) !=
+              count(../attribute::* | ../namespace::*)">
         <xsl:copy-of select="."/>
       </xsl:when>
       <xsl:otherwise>
-        <xsl:if test="not(. = ../attribute::*[name()])">
+        <xsl:if test="count(. | ../namespace::*) = count
(../namespace::*)">
           <xsl:text>xmlns</xsl:text>
           <xsl:if test="name()">:</xsl:if>
         </xsl:if>
$


Now correct output is generated for your sample:
$ xsltproc --stringparam xpathpar "//namespace::*" dynxp.xsl i.xml

-------------------------------------------------------------------------------
xmlns:xml="http://www.w3.org/XML/1998/namespace";
-------------------------------------------------------------------------------
xmlns:a="http://my.namespace/";
-------------------------------------------------------------------------------
xmlns:xs="http://www.w3.org/2001/XMLSchema";
$
$ xsltproc --stringparam xpathpar "//attribute::*" dynxp.xsl i.xml

-------------------------------------------------------------------------------
targetNamespace="http://my.namespace/";
$
$ xsltproc --stringparam xpathpar "//node()" dynxp.xsl i.xml

-------------------------------------------------------------------------------
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema";
xmlns:a="http://my.namespace/"; targetNamespace="http://my.namespace/"/>
$


[1]
http://stamm-wilbrandt.de/en/xsl-list/dynxp.xsl

[2]
https://www.ibm.com/developerworks/forums/thread.jspa?messageID=14455521&#14511477


Mit besten Gruessen / Best wishes,

Hermann Stamm-Wilbrandt
Developer, XML Compiler, L3
WebSphere DataPower SOA Appliances
----------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294



From:       Michael Kay <mike@xxxxxxxxxxxx>
To:         xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Date:       08/17/2010 02:56 PM
Subject:    Re: [xsl] Q: XSLT 1.0 output of namespace




> In getting to the solution below I found that
>    ". = ../namespace::*[name()]"
> as "is-namespace()" test is even simpler than Michael's
>    "count(. | ../@*) != count(../@*)".
>
> Similarly ". = ../attribute::*[name()]" can be used as "is-attribute()".
>
>

It might be simpler, but it's wrong. Firstly, the expression
attribute::*[name()] is rather pointless: it selects all attribute that
have a name, and all of them do. While namespace::*[name()] selects all
namespaces except the default namespace, so your test will fail for that
one.

Secondly, it's quite possible to have an attribute and a namespace with
the same string-value, for example

<xs:schema xmlns:a="http://my.namespace/";
targetNamespace="http://my.namespace/";>

and in this case your test for a namespace and your test for an
attribute will both return true.

Michael Kay
Saxonica

Current Thread