Subject: Re: [xsl] Is XPath and/or XSLT designed such that I should never have to write special case code? From: "Eliot Kimber ekimber@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Tue, 22 Jun 2021 18:36:05 -0000 |
If I understand what you mean by bspecial case codeb I think you really mean bhandling edge cases in a one-off or clunky kind of wayb. 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 thatbs 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 bgrandparent-*b string) or the equivalent. XSLT says bI canbt 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 bstop recursing and returnb check or delegate to templates from the function. The xsl:iterate instruction provides a new place where you might need bspecial caseb processing, but I think that essentially becomes the same as for recursive functions: you always need a bstop iterating nowb check of some sort (otherwise youbd 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 Ibm in a hurry or the effort simply isnbt 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@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Reply-To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> Date: Tuesday, June 22, 2021 at 12:03 PM To: "xsl-list@xxxxxxxxxxxxxxxxxxxxxx" <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> 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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Is XPath and/or XSLT desi, Michael Kay mike@xxx | Thread | [xsl] fn:contains in sequence – P1, Fiona Chen anonymous |
[xsl] Is XPath and/or XSLT designed, Roger L Costello cos | Date | Re: [xsl] Is XPath and/or XSLT desi, Dimitre Novatchev dn |
Month |