This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Matching and changing attributes.
- To: xsl-list at lists dot mulberrytech dot com
- Subject: Re: [xsl] Matching and changing attributes.
- From: Wendell Piez <wapiez at mulberrytech dot com>
- Date: Wed, 30 May 2001 14:09:39 +0100
- Reply-To: xsl-list at lists dot mulberrytech dot com
At 06:24 PM 5/30/01, Thorbjørn wrote:
>I have a situtation where I would like add a few rules to clean up an
>XHTML-document which uses too many @class attributes.
Cool. As you've probably already figured out, such transforms are often
easily written as variants or extensions to the step-by-step identity
transform (the one given in the spec, XSLT 7.5):
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
>I know that I can match a node with a class-attribute with a specific text,
>but this means that other rules cannot come in play with that node, and it
>would be most intuitive to work on the attribute level.
>
>So my question is,
>
>Given a node with a class attribute, like
>
> <mynode class="somestring"/>
>
>how do I write a template that is fired when <xsl:apply-templates
>match="@*"> is executed, and optionally change the attribute giving the
>result
>
> <mynode class="someotherstring">
You mean <xsl:apply-templates select="@*"/>
^^^^^^
Or its variant (as in the identity transform)
<xsl:apply-templates select="node()|@*"/>
which selects all child nodes (node()) and all attribute nodes (@*) for
processing.
By default, an attribute, once selected, will match the built-in template
<xsl:template match="@*">
<xsl:value-of select="."/>
</xsl:template>
which is no good to you -- you don't want the attribute's value simply
copied (without the attribute itself). The identity transform's template,
containing
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
is much closer. Note that in the case of attributes, there are no
attributes or child nodes, so the apply-templates inside the xsl:copy does
nothing. But the attribute itself gets copied (not just its value but the
whole node).
Now this would work; except sometimes you don't want to copy. (When? when
your attribute is a 'class' attribute with certain unacceptable values.) So
you write a specialized template for those cases:
<xsl:template match="@class">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test=".='badvalue'">
<xsl:text>goodvalue</xsl:text>
</xsl:when>
<xsl:when test=".='otherbadvalue'">
<xsl:text>othergoodvalue</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
[Note also it's easy to enhance this. So the test
<xsl:when test=".='badvalue'">
<xsl:value-of select="local-name(..)"/>
</xsl:when>
would take the (local) name of the attribute's parent element and pop that
on the class attribute.]
If your stylesheet also includes the identity transform template (which,
you remember, simply copies each node one by one down the tree), it will
still fire this template for any 'class' attribute, because its priority is
higher than that of the identity transform's match="@*". For all other
nodes, it will just copy them over to the result.
Is that something like what you want? The basic trick is to make sure you
are applying templates on the attribute axis (something that doesn't happen
by default), and then to match="@class" and create the replacement
attribute the way you want it in that template.
>(PS: If anyone can point me to a page about how to use both this list and
>Outlook while keeping my sanity, I will appreciate it).
I wish I could. I don't like what Eudora does either. It's that confounded
"support" for HTML, which mangles and hides stuff. I think Eudora is trying
to match features with Outlook. What, it never occurred to those engineers
that people would want to write about code in their e-mail? (Eudora won't
parse HTML if the line doesn't lead off with the code. Maybe Outlook is the
same.)
Good luck,
Wendell
======================================================================
Wendell Piez mailto:wapiez@mulberrytech.com
Mulberry Technologies, Inc. http://www.mulberrytech.com
17 West Jefferson Street Direct Phone: 301/315-9635
Suite 207 Phone: 301/315-9631
Rockville, MD 20850 Fax: 301/315-8285
----------------------------------------------------------------------
Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list