|
Subject: [xsl] Re: XPath: better way to check for text nodes that aren't descendents of x or y nodes? From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Wed, 14 May 2003 21:07:52 +0200 |
Using the wellknown XPath expression for set difference:
$ns1 - $ns2 =
$ns1[not(count(. | $ns2) = count($ns2))]
One would test to see if there is a non-empty set difference between the set
of all text-node descendents and those that are descendents of "llcd:vernac"
or "llcd:gloss" descendents of the current node:
The expression to test is:
descendent::text()[not(count(. | .//*[self::llcd:vernac or
self::llcd:gloss]//text())
=
count(.//*[self::llcd:vernac or
self::llcd:gloss]//text()))
]
Or quite more simple:
count(.//text()) != count(.//*[self::llcd:vernac or
self::llcd:gloss]//text())
> My current test is
> test=".//text()[not(ancestor::llcd:vernac | ancestor::llcd:gloss)]"
In the general case this is not correct, because it will permit "illegal"
text-nodes, which have an llcd:vernac or llcd:gloss ancestor, which is not a
descendent of the current node (but its ancestor).
Apart from this observation, a non-clever XSLT processor will build the
union in the predicate and this is quite expensive operation. I think it
would be more efficient to re-write the expression as:
.//text()[not(ancestor::llcd:vernac or ancestor::llcd:gloss)]
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
"Lars Huttar" <lars_huttar@xxxxxxx> wrote in message
news:002c01c31a33$1a688ea0$250414ac@xxxxxxxxxxxxxx
> Hi all,
> My requirement is to check for validity of certain XML data as follows:
> all text() nodes descended from . must be descendants of either
llcd:vernac
> or llcd:gloss.
> (By the way, if it helps, the llcd:vernac or llcd:gloss will be
descendants
> of . too, not ancestors.)
>
> My current test is
> test=".//text()[not(ancestor::llcd:vernac | ancestor::llcd:gloss)]"
>
> If this test is true, the data is invalid.
>
> But is there a more efficient way to do this?
> Something that checks for llcd:vernac|llcd:gloss along the way,
> instead of going down the descendant axis and then back up the
> ancestor axis (twice)? Something along the lines of
> test="./(not(llcd:vernac|llcd:gloss)/)*/text()"
> where * means "0 or more times".
>
> I guess I could do
> test="count(.//text()) >
> count(.//llcd:vernac//text() | .//llcd:gloss//text())"
> but I'm not sure that's any more efficient.
>
> This is not a big deal, just wanting to be as efficient as reasonably
> possible.
>
> Lars
>
>
> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
>
>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| RE: [xsl] XPath: better way to chec, Michael Kay | Thread | RE: [xsl] XPath: better way to chec, Passin, Tom |
| Re: [xsl] re-ordering an instance t, S Woodside | Date | Re: [xsl] Using or ignoring Types i, Mike Haarman |
| Month |