[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

self axis and attributes


Subject: self axis and attributes
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Fri, 17 Nov 2000 16:20:25 +0000

[Disclaimer: this post contains light-hearted political comment as a
 way of spicing up an otherwise tediously technical XPath question.
 Please don't send me hate mail.]

Hi,

Since David C. showed me the utility of the self:: axis in checking
the identify of an element, I've been using it mercilessly.  For
example, with an input of:

---
<vote xmlns:d="http://www.democrat.org/"
      xmlns:r="http://www.republican.org/">
   <county>Palm Beach</county>
   <d:count>31563</d:count>
   <r:count>23725</r:count>
</vote>
---

I wrote a stylesheet to prove my worth to my new masters (they wooed
me with client-side XSLT! how could I refuse their dark gift?!):

---
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:dem="http://www.democrat.org/"
                xmlns:rep="http://www.republican.org/">

<xsl:template match="vote">
   <xsl:copy>
      <dem:count><xsl:value-of select="rep:count - 432" /></dem:count>
      <xsl:copy-of select="*[not(self::dem:count)]" />
   </xsl:copy>
</xsl:template>

</xsl:stylesheet>
---

Note in the above that the namespaces in the input and the stylesheet
differ from each other: in the input it's 'd', in the stylesheet,
'dem'. The self:: axis handily translates the 'dem' to 'd' when doing
the comparisons: if I were to use:

   *[not(name() = 'dem:count')]

then the original count would get through; if I were to use:

   *[not(local-name() = 'count')]

then I'd lose the Republican count, neither of which would please my
dark lord.

So it was all fine and dandy until the Jewish-Communist conspiracy
changed the XML schema and started using attributes instead of
elements:

---
<vote xmlns:d="http://www.democrat.org/"
      xmlns:r="http://www.republican.org/"
      county="Palm Beach"
      d:count="31563"
      r:count="23725" />
---

I thought I might be able to just add a '@':

---
<xsl:template match="vote">
   <xsl:copy>
      <xsl:attribute name="dem:count">
         <xsl:value-of select="rep:count - 432" />
      </xsl:attribute>
      <xsl:copy-of select="@*[not(self::dem:count)]" />
   </xsl:copy>
</xsl:template>
---

but no! The self:: axis's principal node type is element, and since
the attribute is not a dem:count element, it still gets included! The
best I can do whilst retaining independence between the stylesheet and
source is:

  @*[not(local-name() = 'count' and
         namespace-uri() = document('')/*/namespace::dem)]
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        or hand-code, or variable, or entity

[Please don't tell me to swap the xsl:attribute for the xsl:copy-of to
 override the dem:count - I'm looking for a general solution.]

Am I missing something? Is there any way of testing the identity of
namespaced attributes while retaining independence between the source
and stylesheet and without testing the namespace-uri()?

Thanks for your help,

Jeni
---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords