Subject: Re: [xsl] For-each adds whitespace per iteration: why? From: Eliot Kimber <ekimber@xxxxxxxxxx> Date: Fri, 10 Jan 2014 12:59:44 -0600 |
Ah, that explains it. I have gotten in the habit of preferring +ADw-xsl:sequence+AD4- over +ADw-xsl:value-of+AD4- but this is apparently one place where I should not have. A subtle aspect of the spec. I+IBk-m glad my understanding of +IBw-concatenation+IB0- in this context was incorrect. The key bit from 5.7.1 appears to step 3 of the sequence processing rules: +ACI-3. Any consecutive sequence of strings within the result sequence is converted to a single text node, whose string value +ADw-http://www.w3.org/TR/xslt20/+ACM-dt-string-value+AD4- contains the content of each of the strings in turn, with a single space (+ACM-x20) used as a separator between successive strings.+ACI- That makes things clear. Cheers, Eliot -- Eliot Kimber Senior Solutions Architect +ACI-Bringing Strategy, Content, and Technology Together+ACI- Main: 512.554.9368 www.reallysi.com www.rsuitecms.com On 1/10/14, 11:27 AM, +ACI-Michael Kay+ACI- +ADw-mike+AEA-saxonica.com+AD4- wrote: +AD4- +AD4-On 10 Jan 2014, at 17:05, Eliot Kimber +ADw-ekimber+AEA-rsicms.com+AD4- wrote: +AD4- +AD4APg- In the context of writing an XSLT to generate DTD syntax from RNGs (for +AD4APg- DITA 1.3) I discovered that for-each results in whitespace being emitted +AD4APg- for each iteration. This came as a surprise. Reading the spec it says, +AD4APg- under clause 7, Repetition: +AD4APg- +AD4APg- +ACI-For each item in the input sequence, evaluating the sequence +AD4APg-constructor +AD4APg- +ADw-http://www.w3.org/TR/xslt20/+ACM-dt-sequence-constructor+AD4- produces a +AD4APg-sequence +AD4APg- of items (see 5.7 Sequence Constructors +AD4APg- +ADw-http://www.w3.org/TR/xslt20/+ACM-sequence-constructors+AD4-). These output +AD4APg- sequences are concatenated+ADs- ... +AD4APg- +AD4APg- I understand +ACI-These output sequences are concatenated+IB0- to mean that +AD4APg-string +AD4APg- concatenation rules are applied, which explains the white space. +AD4- +AD4-No, this is a concatenation of two or more sequences to produce a single +AD4-sequence. No whitespace is added at this point. +AD4- +AD4APg- +AD4APg- My question: why is for-each defined in this way? +AD4- +AD4-It isn't. +AD4APg- +AD4APg- +AD4APg- I tested this with this little XSLT transform: +AD4APg- +AD4APg- +ADw-?xml version+AD0AIg-1.0+ACI- encoding+AD0AIg-UTF-8+ACI-?+AD4- +AD4APg- +ADw-xsl:stylesheet xmlns:xsl+AD0AIg-http://www.w3.org/1999/XSL/Transform+ACI- +AD4APg- xmlns:xs+AD0AIg-http://www.w3.org/2001/XMLSchema+ACI- +AD4APg- xmlns:xd+AD0AIg-http://www.oxygenxml.com/ns/doc/xsl+ACI- +AD4APg- exclude-result-prefixes+AD0AIg-xs xd+ACI- +AD4APg- version+AD0AIg-2.0+ACIAPg- +AD4APg- +AD4APg- +ADw-xsl:output method+AD0AIg-text+ACI-/+AD4- +AD4APg- +AD4APg- +ADw-xsl:template name+AD0AIg-test-for-each+ACIAPg- +AD4APg- +ADw-xsl:variable name+AD0AIg-strings+ACI- select+AD0AIg-('one', 'two', 'three', +AD4APg-'four')+ACI-/+AD4- +AD4APg- value-of +ACQ-strings+AD0APA-xsl:value-of select+AD0AIgAk-strings+ACI-/+AD4- +AD4APg- for +ACQ-str in +ACQ-strings return concat('/', +ACQ-str, '/')+AD0APA-xsl:sequence +AD4APg- select+AD0AIg-for +ACQ-str in +ACQ-strings return concat('/', +ACQ-str, '/')+ACI-/+AD4- +AD4APg- string-join(+ACQ-strings, '')+AD0APA-xsl:sequence select+AD0AIg-string-join(+ACQ-strings, +AD4APg- '')+ACI-/+AD4- +AD4APg- for-each over strings: +ACIAPA-xsl:for-each select+AD0AIgAk-strings+ACIAPg- +AD4APg- +ADw-xsl:sequence select+AD0AIg-concat('/',.,'/')+ACI-/+AD4- +AD4APg- +ADw-/xsl:for-each+AD4AIg- +AD4APg- +ADw-/xsl:template+AD4- +AD4APg- +AD4APg- +ADw-/xsl:stylesheet+AD4- +AD4APg- +AD4APg- +AD4APg- +AD4APg- Which produces this output using Saxon 9.5.1.2: +AD4APg- +AD4APg- value-of +ACQ-strings+AD0-one two three four +AD4APg- for +ACQ-str in +ACQ-strings return concat('/', +ACQ-str, '/')+AD0-/one/ /two/ /three/ +AD4APg- /four/ +AD4APg- string-join(+ACQ-strings, '')+AD0-onetwothreefour +AD4APg- for-each over strings: +ACI-/one/ /two/ /three/ /four/+ACI- +AD4APg- +AD4-The whitespace is being added as part of the process of constructing your +AD4-final result tree from a sequence of strings. The result tree is +AD4-constructed as a document node, following the rules of 5.7.1 Constructing +AD4-Complex Content +AD4- +AD4-http://www.w3.org/TR/2009/PER-xslt20-20090421/+ACM-constructing-complex- conten +AD4-t +AD4- +AD4-or equivalently the rules applied by the Serializer +AD4- +AD4-http://www.w3.org/TR/xslt-xquery-serialization/+ACM-serdm +AD4- +AD4-The simplest way to avoid the space separation is to construct text nodes +AD4-rather than strings, which happens if you replace xsl+ADs-sequence by +AD4-xsl:value-of in +AD4- +AD4APg- +ADw-xsl:sequence select+AD0AIg-concat('/',.,'/')+ACI-/+AD4- +AD4- +AD4-Michael Kay +AD4-Saxonica +AD4- +AD4APg- +AD4APg- I see that the for-each result is consistent with the flowr expression. +AD4APg- +AD4APg- Is my analysis correct that the only way to construct a string with no +AD4APg- extra whitespace using a loop is to use string-join() as in my test +AD4APg-case? +AD4APg- +AD4APg- For my DTD-generation application that would mean using the for-each +AD4APg-loop +AD4APg- to construct a sequence of strings and then using string-join on the +AD4APg- sequence to avoid additional whitespace. Of course I can simply account +AD4APg- for the space inserted by the concatenation and get the correct +AD4APg-indention +AD4APg- and keep my code a bit simpler. +AD4APg- +AD4APg- Cheers, +AD4APg- +AD4APg- Eliot +AD4APg- +AD4APg- -- +AD4APg- Eliot Kimber +AD4APg- Senior Solutions Architect +AD4APg- +ACI-Bringing Strategy, Content, and Technology Together+ACI- +AD4APg- Main: 512.554.9368 +AD4APg- www.reallysi.com +AD4APg- www.rsuitecms.com +AD4APg- +AD4APg- +AD4APg- +AD4APg- --+//0------------------------------------------------------------------- +AD4APg- XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list +AD4APg- To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/ +AD4APg- or e-mail: +ADw-mailto:xsl-list-unsubscribe+AEA-lists.mulberrytech.com+AD4- +AD4APg- --+//0--- +AD4APg- +AD4- +AD4- +AD4---+AH4------------------------------------------------------------------ - +AD4-XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list +AD4-To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/ +AD4-or e-mail: +ADw-mailto:xsl-list-unsubscribe+AEA-lists.mulberrytech.com+AD4- +AD4---+AH4--- +AD4-
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] For-each adds whitespace , Michael Kay | Thread | Re: [xsl] For-each adds whitespace , Eliot Kimber |
Re: [xsl] For-each adds whitespace , David Carlisle | Date | Re: [xsl] For-each adds whitespace , Eliot Kimber |
Month |