Re: [xsl] XPath expression to check that there are no intervening elements?

Subject: Re: [xsl] XPath expression to check that there are no intervening elements?
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 20 Jul 2016 08:35:59 -0000
I did some timings:

Costello 1 - 0.875ms

doc ! (count(B) eq (B[last()]/count(preceding-sibling::*)+1 -
B[1]/count(preceding-sibling::*)))

Kay 1 - 0.299ms

doc ! (empty((* except B) [following-sibling::B and preceding-sibling::B]))

Kay 2 - 0.423ms

doc ! empty(B/following-sibling::*[not(self::B)]/following-sibling::B)

Holman 1 - 1.215ms

doc ! (count(B[last()]/preceding-sibling::*[not(self::B)]) =
count(B[1]/preceding-sibling::*[not(self::B)]))

Holman 2 - 0.416ms

doc ! (string( generate-id( B[1]/preceding-sibling::*[not(self::B)][1] ) ) =
string( generate-id( B[last()]/preceding-sibling::*[not(self::B)][1] ) ))

Novatchev 1 - 0.318ms

doc ! (not(B[1]/following-sibling::node()[not(position() >
../count(B))][not(self::B)]))

Novatchev 2 - 0.416ms

doc ! (not(node()[. >> ../B[1] and . << ../B[last()]][not(self::B)]))

Holman 3 - 0.277ms

doc ! (B  and  not(
B[1]/following-sibling::*[not(self::B)][1]/following-sibling::B ))

Kay 3 - 32.18ms (ouch!)

doc ! (let $fsm := map{
 0: function($x) {if ($x[self::B]) then 1 else 0},
 1: function($x) {if ($x[self::B]) then 1 else 2},
 2: function($x) {if ($x[self::B]) then 3 else 2},
 3: function($x) {3}
} return
(fold-left(*, 0, function($state, $node){$fsm($state)($node)}) ne 3))

Kay 4 - 2.54ms

doc ! (not(matches(string-join(* ! (if (self::B) then "B" else "A"), ""),
"BA+B")))

Which all goes to show, that you never know until you measure it.

These were measured with a source document of the form

<doc><A/><B/><C/>...(*10000)<B/><A/></doc>

The results might of course be completely different with a different source
document.

Measurements made using Saxon 9.7++ using XQuery from the command line, with
the -repeat:50 and -t options, taking the average execution time, which
ignores document build time and query compilation time.

Ken's solution was indeed the fastest.

Michael Kay
Saxonica

Current Thread