Re: [xsl] Determining the type of attribute within the matching template

Subject: Re: [xsl] Determining the type of attribute within the matching template
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sat, 8 Feb 2003 14:14:36 +0000
Hi James,

> I have a template that catches all element and attribute nodes
>
> <template match="*|@*">
>     <choose>
>         <!-- string literal objects -->
>         <when test="self::text()[normalize-space(.) != '']">
>         </when>
>         <!-- resource types -->
>         <when test="self::@rdf:resource">
>         </when>
>         <!-- datatypes -->
>         <when test="self::@rdf:datatype">
>         </when>
>         <!-- complex objects -->
>         <when test="self::*">
>         </when>
>     </choose>
> </template>
>
> This gives an error with the test self::@rdf:resource

In an expression, the @ is a shorthand for the axis attribute::, so
the above test expands to:

  self::attribute::rdf:resource

i.e. to a step with two axes in it, which isn't allowed.

When you use a name test in a step, the step matches nodes with that
name of the "primary node type" for the axis. For the attribute::
axis, this is attributes, while for the self:: axis (and most other
axes) it's elements. That means that self::rdf:resource always tests
whether the current node is a rdf:resource *element* rather than
attribute, and in fact there is no way to test the name of an
attribute that is the current node aside from with the local-name()
and namespace-uri() functions (and the name() function, but I'd only
use that if you were dealing with attributes in no namespace).

In the case above, I think you'd be a lot better off splitting the
<xsl:choose> into multiple templates:

<xsl:template match="*|@*">
  ...
  <xsl:apply-templates select="." mode="content" />
  ...
</xsl:template>

<!-- string literal objects -->
<xsl:template match="text()[normalize-space(.) != '']" mode="content">
  ...
</xsl:template>

<!-- resource types -->
<xsl:template match="@rdf:resource" mode="content">
  ...
</xsl:template>

<!-- datatypes -->
<xsl:template match="@rdf:datatype" mode="content">
  ...
</xsl:template>

<!-- complex objects -->
<xsl:template match="*" mode="content">
  ...
</xsl:template>

<!-- anything else -->
<xsl:template match="node() | @*" mode="content" priority="-10" />

Cheers,

Jeni

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


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


Current Thread