xsl-list
[Top] [All Lists]

Re: [xsl] Multiple elements condition

2007-08-30 15:45:00
Hi Wendell,


Wendell Piez wrote:

So here's my style question of the month. In XSLT 2.0, should I prefer:

thanks, do you make one up for every month? Would be nice ;)


exists(para[2]) and not(exists(para[3]))

or

exists(para[2]) and empty(para[3])

? Is there ever any difference in functionality? I think the first is marginally more legible, but maybe the second gets out of the gate a microsecond faster.

I think the context of the problem has a lot to do with it for what your coding style will be. If it is a select statement and you only want to select the second para when there's no third para, I'd choose:

  <xsl:apply-templates select="para[2][not(../para[3])]" />

I also like the following, in terms of style and conciseness, to select an element when there is a following sibling (actually, the opposite of the original question):

  <xsl:apply-templates select="para[3]/../para[2]" />



If I need the statement in an if-expression or other conditional, I think, in terms of style, than I like the following:

 count(para[position() = (2,3)]) = 1

it has, I think, the added benefit that you use counting on a selection so that unoptimized compilers will perform better. Of course, this is perhaps more readable when it is only about two nodes, but the above is, au contraire, more flexible when it is about a range or a selection.

  count(para[2] | para[3]) = 1


I liked the if-then-else from David. Note that his expression:

   if (para[2]) then empty(para[3]) else false()

can be rewritten into the following (less readable) statement:

 para[2]/(empty(../para[3]) or false())



I find it a pity that the committee did allow for a node test in a predicate, but did not take the chance with the sequences to make behavior and semantics more orthogonal. Wouldn't it be nice if the following were possible (meaning, just like with one number, position() = (2,3))?

  para[2,3]

and, depending on the test we needed, we could write

 count(para[2,3]) = 1

Remark: the following, though legal, would always be true (once the second para is there) because it will return a sequence of 1s, which, compared to a sequence of one 1 will return true:

 para[2,3]/count(.) = 1

Ah well, but that is not gonna work anyway ;)


It's a fun exercise to find out that there are so many ways to express such an easy requirement. XPath certainly is quire versatile.

Cheers,
-- Abel

PS: here's a little follow-up brain teaser. What does the following select? And does it work for the given requirement (select para[2] when there's no para[3])? If not, can you use this approach for the given requirement?

  <xsl:apply-templates select="(para[3]/(), para[2])[2]" />







--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>