This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
self axis and attributes
- To: xsl-list at mulberrytech dot com
- Subject: self axis and attributes
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Fri, 17 Nov 2000 16:20:25 +0000
- Organization: Jeni Tennison Consulting Ltd
- Reply-To: xsl-list at mulberrytech dot com
[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