This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Matching and changing attributes.


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]