[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

For-each adds whitespace per iteration: why?

Subject: For-each adds whitespace per iteration: why?
From: Eliot Kimber <ekimber@xxxxxxxxxx>
Date: Fri, 10 Jan 2014 11:05:53 -0600
 For-each adds whitespace per iteration: why?
In the context of writing an XSLT to generate DTD syntax from RNGs (for
DITA 1.3) I discovered that for-each results in whitespace being emitted
for each iteration. This came as a surprise. Reading the spec it says,
under clause 7, Repetition:

+ACI-For each item in the input sequence, evaluating the sequence constructor
+ADw-http://www.w3.org/TR/xslt20/+ACM-dt-sequence-constructor+AD4- produces a
of items (see 5.7 Sequence Constructors
+ADw-http://www.w3.org/TR/xslt20/+ACM-sequence-constructors+AD4-). These
sequences are concatenated+ADs- if item Q follows item P in the sorted
sequence, then the result of evaluating the sequence constructor with Q as
the context item is concatenated after the result of evaluating the
sequence constructor with P as the context item. The result of the
xsl:for-each +ADw-http://www.w3.org/TR/xslt20/+ACM-element-for-each+AD4-
is the concatenated sequence of items.+IB0-

I understand +ACI-These output sequences are concatenated+IB0- to mean that
concatenation rules are applied, which explains the white space.

My question: why is for-each defined in this way? It came as a surprise to
me that constructing a string using for-each resulted in extra and
unwanted whitespace (I have a function that generates strings of blanks of
a specified length so I can do indention of the DTD components and I was
getting off-by-one results in my formatted DTD output).

I tested this with this little XSLT transform:

+ADw-?xml version+AD0AIg-1.0+ACI- encoding+AD0AIg-UTF-8+ACI-?+AD4-
  exclude-result-prefixes+AD0AIg-xs xd+ACI-

  +ADw-xsl:output method+AD0AIg-text+ACI-/+AD4-

  +ADw-xsl:template name+AD0AIg-test-for-each+ACIAPg-
    +ADw-xsl:variable name+AD0AIg-strings+ACI- select+AD0AIg-('one', 'two',
'three', 'four')+ACI-/+AD4-
 value-of +ACQ-strings+AD0APA-xsl:value-of select+AD0AIgAk-strings+ACI-/+AD4-
 for +ACQ-str in +ACQ-strings return concat('/', +ACQ-str,
select+AD0AIg-for +ACQ-str in +ACQ-strings return concat('/', +ACQ-str,
 string-join(+ACQ-strings, '')+AD0APA-xsl:sequence
 for-each over strings: +ACIAPA-xsl:for-each select+AD0AIgAk-strings+ACIAPg-
  +ADw-xsl:sequence select+AD0AIg-concat('/',.,'/')+ACI-/+AD4-


Which produces this output using Saxon

 value-of +ACQ-strings+AD0-one two three four
 for +ACQ-str in +ACQ-strings return concat('/', +ACQ-str, '/')+AD0-/one/
/two/ /three/
 string-join(+ACQ-strings, '')+AD0-onetwothreefour
 for-each over strings: +ACI-/one/ /two/ /three/ /four/+ACI-

I see that the for-each result is consistent with the flowr expression.

Is my analysis correct that the only way to construct a string with no
extra whitespace using a loop is to use string-join() as in my test case?

For my DTD-generation application that would mean using the for-each loop
to construct a sequence of strings and then using string-join on the
sequence to avoid additional whitespace. Of course I can simply account
for the space inserted by the concatenation and get the correct indention
and keep my code a bit simpler.



Eliot Kimber
Senior Solutions Architect
+ACI-Bringing Strategy, Content, and Technology Together+ACI-
Main: 512.554.9368

Current Thread


Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
First Name
Last Name
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.