xsl-list
[Top] [All Lists]

Re: [xsl] Is XPath and/or XSLT designed such that I should never have to write special case code?

2021-06-22 13:36:12
If I understand what you mean by “special case code” I think you really mean 
“handling edge cases in a one-off or clunky kind of way”.

 

With XSLT, if you take the general approach of doing as much as possible with 
templates then handling special cases is usually a matter of having templates 
that match on all *distinct* cases and also providing appropriate fallback 
processing. I think that’s fundamentally different from having code *within a 
template* that uses a condition check to handle a special case. 

 

In the case of your ancestry-reporting code, you could have done that easily 
with templates and tunnel parameter that provides the starting node (so you can 
generate the “grandparent-*” string) or the equivalent.

 

XSLT says “I can’t predict what I *might* get but I know what I *expect* and I 
can handle all of those cases using the same fundamental technique: template 
matching.

 

Along those lines, I usually have a catch-all template in each mode that will 
be handling arbitrary input to report things that fell through and were 
therefore not properly handled. That tells me when my code is complete over my 
known input documents (at least as far simply handling each relevant different 
case goes).

 

Within functions that do more involved processing, I either use normal 
recursive processing with the usual “stop recursing and return” check or 
delegate to templates from the function.

 

The xsl:iterate instruction provides a new place where you might need “special 
case” processing, but I think that essentially becomes the same as for 
recursive functions: you always need a “stop iterating now” check of some sort 
(otherwise you’d just use template matching or for-each (in the rare cases 
where for-each is appropriate)).

 

In practice I do sometimes find myself using xsl:if or xsl:choose as an 
expedience instead of using the more appropriate template-based logic when I’m 
in a hurry or the effort simply isn’t justified by the current code. But 
usually I regret that later and end up putting in the templates.

 

As others have mentioned, you can also avoid special cases by using a 
multi-stage pipeline that normalizes the data in whatever way is needed to 
eliminate special cases. That creates a clearer separation of concerns and 
simplifies the logic of the follow-on processing.

 

Cheers,

 

Eliot

 

--

Eliot Kimber

http://contrext.com

 

 

 

From: "Roger L Costello costello(_at_)mitre(_dot_)org" 
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com>
Reply-To: <xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Date: Tuesday, June 22, 2021 at 12:03 PM
To: "xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com" 
<xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
Subject: [xsl] Is XPath and/or XSLT designed such that I should never have to 
write special case code?

 

Hi Folks,

 

I think special case code is evil. 

 

To explain what I mean by "special case code" let's take its opposite: code 
selects what is desired under any condition. 

 

So, by "special case code" I mean extra code that is written for dealing with 
special conditions. 

 

Last week I posted the following XPath expression to fetch the <Row> element 
where Cell[1]/Data equals $element and Cell[2]/Data equals $parent.

 

$document/Row[Cell[1]/Data eq $element][Cell[2]/Data eq $parent]

 

However, when $parent is empty, the XPath expression fails. 

 

I was all set to write special case code:

 

<xsl:if test="empty(Cell[2]/Data)"> do something </xsl:if>

 

Bad, bad, bad.

 

But then Mukul showed me an XPath expression that works correctly -- whether 
$parent is empty or not -- without any special case code:

 

$document/Row[Cell[1]/Data eq $element][Cell[2]/string(Data) eq $parent]

 

Awesome!

 

Today I was writing some XSLT to generate a bunch of rows showing, for each 
element in an XML document, its name, the name of its parent, the name of its 
grandparent, and the name of its great-grandparent:

 

<xsl:template match="*">

    <row>

        <element><xsl:value-of select="name(.)"/></element>

        <parent-element><xsl:value-of select="name(..)"/></parent-element>

        <grandparent-element><xsl:value-of 
select="name(../../..)"/></grandparent-element>

        <great-grandparent-element><xsl:value-of 
select="name(../../../..)"/></great-grandparent-element>

    </row>

    <xsl:apply-templates select="*" />

</xsl:template>

 

Obviously as the XSLT traverses through an XML document some elements don't 
have a great-grandparent or a grandparent or even a parent. But I didn't need 
to write special case code to check those conditions. That is terrific!

 

Question #1: is XPath and/or XSLT designed such that I should never have to 
write special case code? 

 

Question #2: If I find myself writing special case code, should I stop and say, 
"How can I modify this XPath and/or XSLT so that I do not have to write special 
case code?

 

/Roger



 

 

 
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--
<Prev in Thread] Current Thread [Next in Thread>
  • Re: [xsl] Is XPath and/or XSLT designed such that I should never have to write special case code?, Eliot Kimber ekimber(_at_)contrext(_dot_)com <=