xsl-list
[Top] [All Lists]

Re: [xsl] I output a tab character, then the output file contains space, tab, space ... why?

2016-04-08 12:52:00
In your second problem solution I would use a FLOWR statement to construct
the value rather than using for-each:

<xsl:variable name="result" as="xs:string*"
  select="for $item in $foo
              Return f:compute-value($item)"
/>
<xsl:sequence select="result"/>

And of course you could do the string-join there as well.

As far as I can tell the only reason to really need to use for-each in
XSLT 2 is to make something the current context where you then need to do
instructions that operate only on the current context (meaning you can't
just put the thing in a variable and the process that). And off the top of
my head I can't think of what that might be although I've had to do it
recently for something.

In functions I always use the result/sequence pattern simply to make it
easy to report the result before returning it should I need to debug the
function's behavior.

Cheers,

E.
----
Eliot Kimber, Owner
Contrext, LLC
http://contrext.com




On 4/8/16, 12:34 PM, "Costello, Roger L. costello(_at_)mitre(_dot_)org"
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:

Hi Folks,

Thank you very much Martin, Michael, and Eliot. Simply superb.

Below I summarize the problem and the solution.

-----------------------------
Problem Statement:
-----------------------------

The below XSLT program loops over each value in a sequence and separates
the sequence values by a tab (hex 9) character. When the output file is
opened in a hex editor we see 3 characters separating the sequence
values: 

      space (hex 20), tab (hex 9), and space (hex 20)

Problem: How can we avoid getting space characters surrounding the tab?

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                          version="2.0">
   
   <xsl:output method="text" />
   
   <xsl:variable name="headers" select="('A', 'B')"/>
   <xsl:variable name="field-separator"
select="codepoints-to-string(9)"/>
   
   <xsl:template match="/">
       <xsl:for-each select="$headers">
           <xsl:sequence select="." />
           <xsl:sequence select="$field-separator"/>
       </xsl:for-each>
   </xsl:template>
   
</xsl:stylesheet>

--------------
Solution:
--------------

The following value-of element will generate the desired output, without
space (hex 20) characters surrounding the tab (hex A) character:

     <xsl:value-of select="$headers" separator="{$field-separator}"/>

Here is an alternate (equivalent) solution which uses XPath to solve the
problem:

     <xsl:sequence select="string-join($headers, $field-separator)"/>

------------------
Problem #2:
------------------

Unlike the above case, in this case there is not a predetermined sequence
of values to be output. Rather, the sequence of values to be output are
determined at run-time. We need to loop over some values, compute an
appropriate value to output, and then follow the output value with a tab
(hex 9). Like this:

<xsl:for-each select="foo">
      <xsl:variable name="value" select="f:compute-value(.)"/>
      <xsl:sequence select="$value" />
      <xsl:sequence select="$field-separator"/>
</xsl:for-each>

Problem: How can we output a tab (hex 9) without also getting the space
(hex 20) characters surrounding the tab character?

--------------
Solution:
--------------

Replace the above loop with this value-of element:

     <xsl:value-of select="f:get-sequence($foo)"
separator="{$field-separator}"/>

Create a function which returns just the sequence of values (no field
separators):

<xsl:function name="f:get-sequence" as="xs:string*">
      <xsl:param name="foo" />
      
      <xsl:for-each select="foo">
              <xsl:variable name="value" select="f:compute-value(.)"/>
              <xsl:sequence select="$value" />
      </xsl:for-each>

</xsl:function>


--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>