RE: [xsl] 3 XSLT2 quickies

Subject: RE: [xsl] 3 XSLT2 quickies
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 17 Mar 2006 09:53:14 -0000
> Can anyone help me sort of (I don't have a running Saxon around):
> 
> 1) If the element a is declared with, say, the simple 
> nonatomic IDREFS 
> type as its simpleContent
> 
> and I have an instance document with
> 
> <a> foo bar baz</a>
> 
> and that a element becomes the context node for
>   <value-of select="."/>
> 
> I should get as output the (one) text node with
> foo bar baz
> 
> right? But really, behind the scenes, it was atomized and 
> re-de-atomized 
> :), so I assume that
>   <value-of select="." separator="-ostrich-"/>
> 
> should get me
> foo-ostrich-bar-ostrich-baz

Correct. The detailed rules are in 5.7.2:

#Zero-length text nodes in the sequence are discarded.

#Adjacent text nodes in the sequence are merged into a single text node.

#The sequence is atomized.

#Every value in the atomized sequence is cast to a string.

#The strings within the resulting sequence are concatenated, with a
(possibly zero-length) separator inserted between successive strings. 

> 
> If not, well what about:
>   <value-of select="./text()" />
> or
>   <value-of select="./text()" separator="-ostrich-"/>
> 
> My _understanding_ is that they should both just output
> 
> foo bar baz
> 
> because text() doesn't atomize, but I am open for any objections.

Actually the text nodes *are* atomized, but the result of atomizing a text
node is a single string, regardless of the type annotation of the parent
element.

Note also that the rule about concatenating text nodes comes into play here:
if your input were

<a>foo<!--hey!-->bar</a>

the result would be "foobar" rather than "foo-ostrich-bar" because of the
rule that adjacent text nodes are concatenated before atomization.

> 
> document-node(schema-element(rubberduck))
> 
> node test is one bastard to analyze (I'm doing static 
> analysis on XSLT): 
> It tests not one, but tow nodes.
> 
> Are there any great dangers in converting it to
> 
> document-node()[child::schema-element(rubberduck)]
> 

Obviously this only works when used as a step in a path expression, or as a
pattern: not for example when used in an "as" attribute.

Technically I think the rewrite is more like:

document-node()[count(child::*)=1 and count(child::text()=0) and
(child::schema-element(rubberduck))]

Michael Kay
http://www.saxonica.com/

Current Thread