views:

4793

answers:

3

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>
+1  A: 

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
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
+1  A: 

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
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 ? How is that done? Ideally, I'd like a way to do this without passing EOL via a param.
Greg Mattes
Why does it have to be inside of xsl:text? Why not a few <xsl:value-of statements in a row?
jsight
+1  A: 

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>
Mads Hansen