Re: [xsl] [XSLT 1.0] Q: recursively eliminate empty nodes

Subject: Re: [xsl] [XSLT 1.0] Q: recursively eliminate empty nodes
From: Brandon Ibach <brandon.ibach@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 10 Nov 2010 02:04:20 -0500
On Mon, Nov 8, 2010 at 5:16 PM, Andriy Gerasika
<andriy.gerasika@xxxxxxxxx> wrote:
> http://www.devguru.com/technologies/xslt/quickref/xslt_element_template.html
> fragment
> The optional priority attribute is a real number that ranges from -9.0 to
> 0.0 to 9.0 that sets the priority of importance for a template.

Regarding the "priority" attribute, the XSLT 1.0 recommendation only
says "The value of this must be a real number (positive or negative),
matching the production Number with an optional leading minus sign
(-)." [1]  No range of allowed values is given, so the priority could
be specified to be less than -9.0, or greater than 9.0.

> sorry, I thought
> <xsl:template match="@*|node()">
> and
> <xsl:template match="*[not(node())]" />
> have the same default priority

These two templates would have default priorities of -0.5 and 0.5, respectively.

The rules for default priority (also at [1] for XSLT 1.0 or [2] for
XSLT 2.0) have always been difficult for me to remember, probably
because they are defined in somewhat abstract terms in the
recommendation.  I decided it was a good time to put together
something to help myself keep them straight.  Maybe it will help
others here, too.

Here's a breakdown of various types of XSLT 1.0 and XSLT 2.0 patterns
grouped by their default priority values.  (Someone please correct me
if any of this is either inaccurate or incomplete.)

Notes: "elem" represents any element name, "attr" represents any attribute name,
              "pre" represents any namespace prefix, "pi" represents
any PI target name,
              "type" represents any type name (XSLT 2.0 only)
          A "[child::]" or "[attribute::]" at the start of a pattern
means it has the same
              priority with or without the explicit axis specifier.
          A pattern consisting of multiple alternatives separated by
"|" is treated like
              a set of templates, one for each alternative.  Each
alternative could have
              a different priority, though in the "@* | node()"
example, both "@*" and
              "node()" have priority -0.5.
----------
Priority 0.25: (all XSLT 2.0 only)
    [child::]element(elem, type)
    [child::]schema-element(elem)
    [child::]document-node(element(elem, type))
    [child::]document-node(schema-element(elem))
    [attribute::]attribute(attr, type)
    [attribute::]schema-attribute(attr)
    @attribute(attr, type)
    @schema-attribute(attr)
Priority 0:
    [child::]elem
    [child::]pre:elem
    [child::]processing-instruction('pi')
    [child::]processing-instruction(pi)   (XSLT 2.0 only)
    [child::]element(elem)   (XSLT 2.0 only)
    [child::]element(*, type)   (XSLT 2.0 only)
    [child::]document-node(element(elem))   (XSLT 2.0 only)
    [child::]document-node(element(*, type))   (XSLT 2.0 only)
    @attr
    @pre:attr
    attribute::attr
    attribute::pre:attr
    [attribute::]attribute(attr)   (XSLT 2.0 only)
    [attribute::]attribute(*, type)   (XSLT 2.0 only)
    @attribute(attr)   (XSLT 2.0 only)
    @attribute(*, type)   (XSLT 2.0 only)
Priority -0.25:
    [child::]pre:*
    [child::]*:elem   (XSLT 2.0 only)
    @pre:*
    @*:attr   (XSLT 2.0 only)
    attribute::pre:*
    attribute::*:attr   (XSLT 2.0 only)
Priority -0.5:
    [child::]*
    [child::]node()
    [child::]text()
    [child::]comment()
    [child::]processing-instruction()
    [child::]element()   (XSLT 2.0 only)
    [child::]element(*)   (XSLT 2.0 only)
    [child::]document-node(element())   (XSLT 2.0 only)
    [child::]document-node(element(*))   (XSLT 2.0 only)
    @*
    attribute::*
    @node()
    attribute::node()
    [attribute::]attribute()   (XSLT 2.0 only)
    [attribute::]attribute(*)   (XSLT 2.0 only)
    @attribute()   (XSLT 2.0 only)
    @attribute(*)   (XSLT 2.0 only)
    /   (XSLT 2.0 only -- priority 0.5 in XSLT 1.0)
Priority 0.5: Everything else, including any pattern that uses "/",
"//", "[]" or any axis other than "child" or "attribute".
----------

> I just use identity template priority -9 as universal for life

As shown above, this type of template will always get the lowest
default priority (-0.5), so it isn't usually necessary to set it's
priority, since anything more specific will get a higher default
priority.  This could only be defeated if some template gets a
negative priority (less than -0.5).

That said, one of the most important criteria for something being a
good practice is that it is done consistently.  Just be aware that
this isn't a guaranteed solution if someone else works on your code,
with their own ideas about good practices, since they could specify a
lower priority on a template.

-Brandon :)

[1] http://www.w3.org/TR/xslt#conflict
[2] http://www.w3.org/TR/xslt20/#conflict

Current Thread