XSL 在 XML CDATA 中保留 Space
XSL Preserve Space in XML CDATA
我尝试了多种解决方案,但似乎无法正常工作。
我正在进行 XML 到 XML (FOP) 的 XSL 转换以创建 PDF。来源 XML 具有 元素,其内容以 CDATA 声明开头。转换删除换行符。
示例输入 XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<myxml>
<code><![CDATA[import java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
]]></code>
</myxml>
XSL 示例:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="fo"
>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" cdata-section-elements="code"/>
<xsl:preserve-space elements="code" />
<fo:block font-family="Courier New" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4">
<fo:block>
<xsl:text>Copy</xsl:text>
<xsl:copy>
<xsl:value-of select="code"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Copy Text</xsl:text>
<xsl:copy>
<xsl:value-of select="code/text()"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<xsl:value-of select="code"/>
</fo:block>
<fo:block>
<xsl:text>Normalise space</xsl:text>
<value-of select="normalize-space(code)" disable-output-escaping="yes"/>
</fo:block>
<fo:block>
<xsl:text>Copy with extra CDATA wrapper?</xsl:text>
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="code"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Again, an attempt to wrap</xsl:text>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="code" />
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</fo:block>
</fo:block>
排列...
我已经尝试了以下所有排列:
- 全局声明:同时使用 cdata-section 和 preserve-space,仅使用其中之一
- 来源 xml 文档 containing/not 在代码元素和外部元素上都包含 xml:space="preserve"。
一共6个排列。
这些设置对我来说似乎没什么区别。以下是每个测试块的输出:
- 块'Copy':空(无文本输出)
- 块'Copy Text':空(无文本输出)
- 块'Original':代码,但所有换行符都被删除
- 块'Normalise space':空(无文本输出)
- 块'Copy with extra CDATA wrapper?':空(无文本输出)
- 块'Again, an attempt to wrap':代码,但删除了所有换行符
让我们澄清一下您的代码中反映的一些基本误解。
- 如@michael.hor257k 所述,您没有
xsl:template
结构体。这对于简化的样式表来说实际上是可以的
你正在尝试,但这种形式没有 xsl:stylesheet
根
元素;它只是以 XML 根元素开始
输出 XML。然后它从输入中提取 XML 正如你正在做的那样
xsl:value-of/@select
构造。所以,主要修复 #1 是添加
<xsl:template match="/">...
或删除 <xsl:stylesheet>
。出色地
选择第二个选项(简化的样式表),因为它似乎是您喜欢的。
- 下一步,意识到你的 XPaths 没有 select 任何东西,所以
你所有的测试用例都没有证明什么。主要修复#2:而不是
selecting
"code/'
, select "/myxml/code"
在你所有的测试中
案例。
以下是经过上述更改(以及其他一些小修复)的测试用例:
<?xml version="1.0" encoding="iso-8859-1"?>
<fo:block font-family="Courier New" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xsl:version="1.0">
<fo:block>
<xsl:text>Copy</xsl:text>
<xsl:copy>
<xsl:value-of select="/myxml/code"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Copy Text</xsl:text>
<xsl:copy>
<xsl:value-of select="/myxml/code/text()"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<xsl:value-of select="/myxml/code"/>
</fo:block>
<fo:block>
<xsl:text>Normalise space</xsl:text>
<xsl:value-of select="normalize-space(code)" disable-output-escaping="yes"/>
</fo:block>
<fo:block>
<xsl:text>Copy with extra CDATA wrapper?</xsl:text>
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="/myxml/code"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Again, an attempt to wrap</xsl:text>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="/myxml/code" />
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</fo:block>
</fo:block>
运行 以上 XSLT 针对您的输入 XML 产生更有用的测试结果:
<?xml version="1.0" encoding="UTF-8"?><fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Courier New" font-size="12pt" color="black" space-after="12pt" space-before="12pt" space-before.precedence="4"><fo:block>Copyimport java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
</fo:block><fo:block>Copy Textimport java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
</fo:block><fo:block>Originalimport java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
</fo:block><fo:block>Normalise space</fo:block><fo:block>Copy with extra CDATA wrapper?<![CDATA[import java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
]]></fo:block><fo:block>Again, an attempt to wrap
<![CDATA[
import java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
]]>
</fo:block></fo:block>
我相信从那里您将能够确定产生您寻求的结果的测试用例结果。
将您的代码放在 fo:block 中并设置以下属性来控制空格和回车符的处理 returns:
像这样:
<fo:block>
<xsl:text>Original</xsl:text>
<fo:block linefeed-treatment="preserve"
white-space-collapse="false"
white-space-treatment="preserve">
<xsl:value-of select="code"/>
</fo:block>
</fo:block>
(代表 OP 发布。此解决方案是对问题的编辑,因此我已回滚该编辑并在此处发布。)
输入XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<solution>
<solution_name>A Set of Functions</solution_name>
<description>Just for the sake of example</description>
<functions>
<function>
<code><![CDATA[function String getStringSafely(String textToCheck, String defaultValue) {
if (textToCheck == null || textToCheck.length() <= 0) {
return defaultValue;
}
return textToCheck;
}
]]></code>
</function>
<function><code><![CDATA[import java.nio.charset.Charset;
import com.example.library.Something;
function String doSomething(String key) {
if (key == null || key.length() <= 0) {
return "";
}
System.out.println(String.format("Yep, got a value[%1$s]", key));
}
]]></code>
</function>
</functions>
</solution>
XSL 示例:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="fo"
>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" cdata-section-elements="code"/>
<xsl:preserve-space elements="code" />
<xsl:template match="solution">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="solution-page">
<fo:region-body margin="1in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="solution-page">
<fo:flow flow-name="xsl-region-body" id="solution">
<fo:block text-align="center"
space-after="40pt" space-before="100pt" space-after.precedence="3"
font-family="Helvetica" font-weight="bold" font-size="14pt" color="#0050B2" >
<xsl:value-of select="solution_name"/>
</fo:block>
<fo:block font-family="Helvetica" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4">
<xsl:value-of select="description"/>
</fo:block>
<xsl:for-each select="functions">
<xsl:variable name="this" select="." />
<xsl:call-template name="solution_functions">
<xsl:with-param name="data" select="$this"/>
</xsl:call-template>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template name="solution_functions">
<xsl:param name="data"/>
<fo:block id="functions" break-before="page"
font-family="Helvetica"
font-weight="bold"
font-size="14pt"
color="#0050B2" space-after="12pt"
space-before="16pt" space-after.precedence="3">
Functions
</fo:block>
<xsl:for-each select="$data/function">
<xsl:variable name="this" select="." />
<xsl:call-template name="present_function">
<xsl:with-param name="data" select="$this"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="present_function">
<xsl:param name="data"/>
<fo:block
font-family="Helvetica"
font-weight="bold"
font-size="12pt"
space-after="12pt"
space-before="16pt" space-after.precedence="3">
Code
</fo:block>
<fo:block font-family="Helvetica" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4">
<fo:block>
<xsl:text>This works! Thanks ...</xsl:text>
<fo:block linefeed-treatment="preserve"
white-space-collapse="false"
white-space-treatment="preserve">
<xsl:value-of select="$data/code"/>
</fo:block>
</fo:block>
<fo:block>
[ All following examples were part of the original post. The above is the one which works. The below, kept for future reference to original question. ]
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<fo:block linefeed-treatment="preserve"
white-space-collapse="false"
white-space-treatment="preserve">
<xsl:value-of select="$data/code"/>
</fo:block>
</fo:block>
<fo:block>
<xsl:text>Copy</xsl:text>
<xsl:copy>
<xsl:value-of select="$data/code"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Copy Text</xsl:text>
<xsl:copy>
<xsl:value-of select="$data/code/text()"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<xsl:value-of select="$data/code"/>
</fo:block>
<fo:block>
<xsl:text>Normalise space</xsl:text>
<value-of select="normalize-space($data/code)" disable-output-escaping="yes"/>
</fo:block>
<fo:block>
<xsl:text>Copy with extra CDATA wrapper?</xsl:text>
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="$data/code"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Again, an attempt to wrap</xsl:text>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="$data/code" />
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</fo:block>
</fo:block>
</xsl:template>
</xsl:stylesheet>
我尝试了多种解决方案,但似乎无法正常工作。
我正在进行 XML 到 XML (FOP) 的 XSL 转换以创建 PDF。来源 XML 具有 元素,其内容以 CDATA 声明开头。转换删除换行符。
示例输入 XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<myxml>
<code><![CDATA[import java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
]]></code>
</myxml>
XSL 示例:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="fo"
>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" cdata-section-elements="code"/>
<xsl:preserve-space elements="code" />
<fo:block font-family="Courier New" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4">
<fo:block>
<xsl:text>Copy</xsl:text>
<xsl:copy>
<xsl:value-of select="code"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Copy Text</xsl:text>
<xsl:copy>
<xsl:value-of select="code/text()"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<xsl:value-of select="code"/>
</fo:block>
<fo:block>
<xsl:text>Normalise space</xsl:text>
<value-of select="normalize-space(code)" disable-output-escaping="yes"/>
</fo:block>
<fo:block>
<xsl:text>Copy with extra CDATA wrapper?</xsl:text>
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="code"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Again, an attempt to wrap</xsl:text>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="code" />
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</fo:block>
</fo:block>
排列... 我已经尝试了以下所有排列:
- 全局声明:同时使用 cdata-section 和 preserve-space,仅使用其中之一
- 来源 xml 文档 containing/not 在代码元素和外部元素上都包含 xml:space="preserve"。
一共6个排列。
这些设置对我来说似乎没什么区别。以下是每个测试块的输出:
- 块'Copy':空(无文本输出)
- 块'Copy Text':空(无文本输出)
- 块'Original':代码,但所有换行符都被删除
- 块'Normalise space':空(无文本输出)
- 块'Copy with extra CDATA wrapper?':空(无文本输出)
- 块'Again, an attempt to wrap':代码,但删除了所有换行符
让我们澄清一下您的代码中反映的一些基本误解。
- 如@michael.hor257k 所述,您没有
xsl:template
结构体。这对于简化的样式表来说实际上是可以的 你正在尝试,但这种形式没有xsl:stylesheet
根 元素;它只是以 XML 根元素开始 输出 XML。然后它从输入中提取 XML 正如你正在做的那样xsl:value-of/@select
构造。所以,主要修复 #1 是添加<xsl:template match="/">...
或删除<xsl:stylesheet>
。出色地 选择第二个选项(简化的样式表),因为它似乎是您喜欢的。 - 下一步,意识到你的 XPaths 没有 select 任何东西,所以
你所有的测试用例都没有证明什么。主要修复#2:而不是
selecting
"code/'
, select"/myxml/code"
在你所有的测试中 案例。
以下是经过上述更改(以及其他一些小修复)的测试用例:
<?xml version="1.0" encoding="iso-8859-1"?>
<fo:block font-family="Courier New" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xsl:version="1.0">
<fo:block>
<xsl:text>Copy</xsl:text>
<xsl:copy>
<xsl:value-of select="/myxml/code"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Copy Text</xsl:text>
<xsl:copy>
<xsl:value-of select="/myxml/code/text()"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<xsl:value-of select="/myxml/code"/>
</fo:block>
<fo:block>
<xsl:text>Normalise space</xsl:text>
<xsl:value-of select="normalize-space(code)" disable-output-escaping="yes"/>
</fo:block>
<fo:block>
<xsl:text>Copy with extra CDATA wrapper?</xsl:text>
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="/myxml/code"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Again, an attempt to wrap</xsl:text>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="/myxml/code" />
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</fo:block>
</fo:block>
运行 以上 XSLT 针对您的输入 XML 产生更有用的测试结果:
<?xml version="1.0" encoding="UTF-8"?><fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" font-family="Courier New" font-size="12pt" color="black" space-after="12pt" space-before="12pt" space-before.precedence="4"><fo:block>Copyimport java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
</fo:block><fo:block>Copy Textimport java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
</fo:block><fo:block>Originalimport java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
</fo:block><fo:block>Normalise space</fo:block><fo:block>Copy with extra CDATA wrapper?<![CDATA[import java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
]]></fo:block><fo:block>Again, an attempt to wrap
<![CDATA[
import java.nio.charset.Charset;
import com.my.library.AClass;
import com.my.library.AnotherClass;
public String getStringValue(String key) {
// Just some ramblings
// Dummy code...
if (key != null && key.length() > 0) {
System.out.println(key);
}
}
]]>
</fo:block></fo:block>
我相信从那里您将能够确定产生您寻求的结果的测试用例结果。
将您的代码放在 fo:block 中并设置以下属性来控制空格和回车符的处理 returns:
像这样:
<fo:block>
<xsl:text>Original</xsl:text>
<fo:block linefeed-treatment="preserve"
white-space-collapse="false"
white-space-treatment="preserve">
<xsl:value-of select="code"/>
</fo:block>
</fo:block>
(代表 OP 发布。此解决方案是对问题的编辑,因此我已回滚该编辑并在此处发布。)
输入XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<solution>
<solution_name>A Set of Functions</solution_name>
<description>Just for the sake of example</description>
<functions>
<function>
<code><![CDATA[function String getStringSafely(String textToCheck, String defaultValue) {
if (textToCheck == null || textToCheck.length() <= 0) {
return defaultValue;
}
return textToCheck;
}
]]></code>
</function>
<function><code><![CDATA[import java.nio.charset.Charset;
import com.example.library.Something;
function String doSomething(String key) {
if (key == null || key.length() <= 0) {
return "";
}
System.out.println(String.format("Yep, got a value[%1$s]", key));
}
]]></code>
</function>
</functions>
</solution>
XSL 示例:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/TR/xhtml1/strict"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="fo"
>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" cdata-section-elements="code"/>
<xsl:preserve-space elements="code" />
<xsl:template match="solution">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="solution-page">
<fo:region-body margin="1in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="solution-page">
<fo:flow flow-name="xsl-region-body" id="solution">
<fo:block text-align="center"
space-after="40pt" space-before="100pt" space-after.precedence="3"
font-family="Helvetica" font-weight="bold" font-size="14pt" color="#0050B2" >
<xsl:value-of select="solution_name"/>
</fo:block>
<fo:block font-family="Helvetica" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4">
<xsl:value-of select="description"/>
</fo:block>
<xsl:for-each select="functions">
<xsl:variable name="this" select="." />
<xsl:call-template name="solution_functions">
<xsl:with-param name="data" select="$this"/>
</xsl:call-template>
</xsl:for-each>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template name="solution_functions">
<xsl:param name="data"/>
<fo:block id="functions" break-before="page"
font-family="Helvetica"
font-weight="bold"
font-size="14pt"
color="#0050B2" space-after="12pt"
space-before="16pt" space-after.precedence="3">
Functions
</fo:block>
<xsl:for-each select="$data/function">
<xsl:variable name="this" select="." />
<xsl:call-template name="present_function">
<xsl:with-param name="data" select="$this"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="present_function">
<xsl:param name="data"/>
<fo:block
font-family="Helvetica"
font-weight="bold"
font-size="12pt"
space-after="12pt"
space-before="16pt" space-after.precedence="3">
Code
</fo:block>
<fo:block font-family="Helvetica" font-size="12pt" color="black"
space-after="12pt" space-before="12pt" space-before.precedence="4">
<fo:block>
<xsl:text>This works! Thanks ...</xsl:text>
<fo:block linefeed-treatment="preserve"
white-space-collapse="false"
white-space-treatment="preserve">
<xsl:value-of select="$data/code"/>
</fo:block>
</fo:block>
<fo:block>
[ All following examples were part of the original post. The above is the one which works. The below, kept for future reference to original question. ]
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<fo:block linefeed-treatment="preserve"
white-space-collapse="false"
white-space-treatment="preserve">
<xsl:value-of select="$data/code"/>
</fo:block>
</fo:block>
<fo:block>
<xsl:text>Copy</xsl:text>
<xsl:copy>
<xsl:value-of select="$data/code"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Copy Text</xsl:text>
<xsl:copy>
<xsl:value-of select="$data/code/text()"/>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Original</xsl:text>
<xsl:value-of select="$data/code"/>
</fo:block>
<fo:block>
<xsl:text>Normalise space</xsl:text>
<value-of select="normalize-space($data/code)" disable-output-escaping="yes"/>
</fo:block>
<fo:block>
<xsl:text>Copy with extra CDATA wrapper?</xsl:text>
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[<![CDATA[]]></xsl:text>
<xsl:value-of select="$data/code"/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</xsl:copy>
</fo:block>
<fo:block>
<xsl:text>Again, an attempt to wrap</xsl:text>
<xsl:text disable-output-escaping="yes">
<![CDATA[
</xsl:text>
<xsl:value-of select="$data/code" />
<xsl:text disable-output-escaping="yes">
]]>
</xsl:text>
</fo:block>
</fo:block>
</xsl:template>
</xsl:stylesheet>