我尝试了各种解决方案,但似乎无法实现这一目标。
我正在进行XML到XML(FOP)的XSL转换以进行PDF创建。源XML具有< code>内容以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>
排列... 我尝试了以下所有排列:
总共有6种排列。
这些设置似乎对我没什么影响。以下是每个测试块的输出:
答案 0 :(得分:2)
(代表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>
答案 1 :(得分:1)
让我们澄清代码中反映的一些基本误解。
xsl:template
结构体。对于简化的样式表,这实际上是可以的
你正在尝试,但这种形式没有xsl:stylesheet
根
元件;它只是从你想要的XML根元素开始
输出XML。然后,它会在您执行时从输入XML中提取
xsl:value-of/@select
构造。因此,主要修复#1是添加
<xsl:template match="/">...
或删除<xsl:stylesheet>
。好
使用第二个选项(简化样式表),因为它似乎是你喜欢的。"code/'
,在所有测试中选择"/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>
针对您的输入XML运行上述XSLT会产生更多有用的测试结果:
<?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>
我相信您可以从中找出产生您所寻求结果的测试用例结果。
答案 2 :(得分:0)
将您的代码放在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="code"/>
</fo:block>
</fo:block>