13

I have an XSL stylesheet with content in an xsl:text node like this:

<xsl:text>
foo
bar
baz
</xsl:text>

The stylesheet itself is a text file with "unix-style" newline line terminators. I invoke this stylesheet on Windows as well as unix-like platforms. It would be nice to have the output conform to the conventions of the platform on which it is invoked.

When I run this stylesheet on Windows, the output has carriage return/newline pairs for everything except the contents of the xsl:text node.

Can I instruct the XSLT processor to translate the newline characters in the content of the xsl:text node into platform specific end-of-lines?

More context: I'm invoking the stylesheet from the Apache Ant 1.7.1 XSLT task like this:

<xslt in="in.xml" out="out.xml" style="stylesheet.xsl"/>

The stylesheet header currently looks like this:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xalan="http://xml.apache.org/xslt"
    exclude-result-prefixes="xalan">
    <!-- contents elided -->
</xsl:stylesheet>
Mathias Müller
  • 22,203
  • 13
  • 58
  • 75
Greg Mattes
  • 33,090
  • 15
  • 73
  • 105

4 Answers4

5

You could define a parameter for the stylesheet like so:

<xsl:param name="br">
    <xsl:text>&#10;</xsl:text>
</xsl:param>

and pass in the appropriate end of line character(s) by using a nested param element in your Ant script. The default in this example would be a Unix-style newline, of course. I think to output the value, you'd have to use:

<xsl:copy-of select="$br"/>

It's verbose, but it works.

Adam Crume
  • 15,614
  • 8
  • 46
  • 50
  • Thanks for the answer! This is a good idea, but I don't think xsl:copy-of can be embedded in the body of xsl:text. Can an entity be defined with the param instead? I can embed things like <, what about &myeol;? How is that done? Ideally, I'd like a way to do this without passing EOL via a param. – Greg Mattes Oct 09 '08 at 16:35
  • Why does it have to be inside of xsl:text? Why not a few – jsight Oct 10 '08 at 16:00
4

If you are calling the transform from Ant, then you can test for the OS using a conditional task with a test for the OS family:

  <condition property="linebreak" value="&#xD;&#xa;">
      <os family="windows"/>
  </condition>
  <condition property="linebreak" value="&#xa;">
      <os family="unix"/>
  </condition>

Then pass that parameter to the XSLT to signal which newline character(s) you want to use.

 <xslt in="data.xml" out="${out.dir}/out.xml">
   <param name="linebreak" expression="${linebreak}" />
 </xslt>
martin clayton
  • 76,436
  • 32
  • 213
  • 198
Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
1

Im not sure how to do the correct newlines automatically (it may depend on the xslt processor you are using), but you may be able to force the newlines in the contents of your text node. \r\n is &#xD; &#xA;, \n is &#xA;, e.g. you'd use:

<xsl:text>foo&#xD;&#xa;bar&#xD;&#xa;</xsl:text> to get the output you're looking for.

Jen A
  • 635
  • 1
  • 8
  • 20
  • Thanks for the answer! Yes, I think that I could do that, but then the output would be wrong in unix-like environments! Instead of hardcoding it one way or the other, I want it to "do the right thing" regardless of where it is invoked. Maybe I should clarify this in the question. Thanks again. – Greg Mattes Oct 08 '08 at 22:53
0

Well, I got mine to work (using Saxon) with a combination of 2 ideas above:

<xsl:param name="br">
        <xsl:text>&#xD;&#xa;</xsl:text>
</xsl:param>

and then using line(s) like these where needed.

<xsl:value-of select="$br" />

Here is my full (but slimline) xsl

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!--<xsl:strip-space elements="*" />-->
  <xsl:output method="text" />
  <!-- <xsl:preserve-space elements="*"/>-->
<xsl:param name="br">
        <xsl:text>&#xD;&#xa;</xsl:text>
</xsl:param>


  <!--  -->
  <xsl:template match="/">


    <xsl:for-each select="//root/Item">

        <xsl:value-of select="@Name" /> <!-- Your xpath will vary of course! -->
        <xsl:value-of select="$br" />

    </xsl:for-each>

</xsl:template>

Again, I am using Saxon %ProgramFiles%\SaxonHE\bin\Transform.exe on a windows 7 x64 machine.

granadaCoder
  • 26,328
  • 10
  • 113
  • 146