在XSLT中生成一个新行
我想为XSLT中的文本输出生成一个换行符。 有任何想法吗?
以下XSL代码将生成换行符 ( 换行符 ):
<xsl:text>
</xsl:text>
对于回车 ,请使用:
<xsl:text>
</xsl:text>
我最喜欢的做法是这样的:
<xsl:stylesheet> <xsl:output method='text'/> <xsl:variable name='newline'><xsl:text> </xsl:text></xsl:variable> <!-- note that the layout there is deliberate --> ... </xsl:stylesheet>
然后,只要你想输出一个换行符(也许在csv中),你可以输出如下内容:
<xsl:value-of select="concat(elem1,elem2,elem3,$newline") />
从xmlinput中输出sql时,我使用了这种技术。 实际上,我倾向于为逗号,引号和换行符创buildvariables。
在xsl:output标签中包含属性Method =“text”,并在适当的位置在XSL中的文字内容中包含换行符。 如果您希望保持XSL的源代码整洁,请使用实体
你想要一个新的线路。
您可以使用: <xsl:text> </xsl:text>
看到这个例子
<xsl:variable name="module-info"> <xsl:value-of select="@name" /> = <xsl:value-of select="@rev" /> <xsl:text> </xsl:text> </xsl:variable>
如果你写在文件如
<redirect:write file="temp.prop" append="true"> <xsl:value-of select="$module-info" /> </redirect:write>
这个variables会产生一个新的行infile:
commons-dbcp_commons-dbcp = 1.2.2 junit_junit = 4.4 org.easymock_easymock = 2.4
我发现了<xsl:text>
字面换行符和使用

。
虽然在我的环境中(使用Saxon和默认的Java XSLT处理器)文字换行符正常工作,但是由.NET环境中运行的另一个组执行时,代码失败。
更改为实体( 

)使我的文件生成代码在Java和.NET上运行一致。
另外,文字换行符很容易被IDE重新格式化,并且当文件被不知情的人维护时可能会不经意间丢失。
我添加了你在这里看到的DOCTYPE
指令:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY nl "
"> ]> <xsl:stylesheet xmlns:x="http://www.w3.org/2005/02/query-test-XQTSCatalog" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
这允许我使用&nl;
而不是

在输出中产生一个换行符。 与其他解决scheme一样,这通常放在<xsl:text>
标签内。
我从我的经验中已经注意到,在<xsl:variable>
子句中生成一个新行是行不通的。 我试图做一些事情:
<xsl:variable name="myVar"> <xsl:choose> <xsl:when test="@myValue != ''"> <xsl:text>My value: </xsl:text> <xsl:value-of select="@myValue" /> <xsl:text></xsl:text> <!--NEW LINE--> <xsl:text>My other value: </xsl:text> <xsl:value-of select="@myOtherValue" /> </xsl:when> </xsl:choose> <xsl:variable> <div> <xsl:value-of select="$myVar"/> </div>
任何我试图放入“新行”(空的<xsl:text>
节点)的东西都不起作用(包括这个页面中的大部分更简单的build议),更不用提HTML这个事实了在那里,所以最终我不得不把它分成2个variables,把它们叫做<xsl:variable>
范围之外,并在它们之间放置一个简单的东西,即:
<xsl:variable name="myVar1"> <xsl:choose> <xsl:when test="@myValue != ''"> <xsl:text>My value: </xsl:text> <xsl:value-of select="@myValue" /> </xsl:when> </xsl:choose> <xsl:variable> <xsl:variable name="myVar2"> <xsl:choose> <xsl:when test="@myValue != ''"> <xsl:text>My other value: </xsl:text> <xsl:value-of select="@myOtherValue" /> </xsl:when> </xsl:choose> <xsl:variable> <div> <xsl:value-of select="$myVar1"/> <br/> <xsl:value-of select="$myVar2"/> </div>
是的,我知道,这不是最复杂的解决scheme,但它的工作原理,只是与XSL分享我的挫折经验;)
恕我直言,没有更多的信息比@Florjon给的是必要的。 也许有些小细节可以理解为什么它有时候不适合我们。
首先, <xsl:text/>
的

(hex)或者

(十进制)将始终有效,但是您可能看不到它。
- HTML标记中没有换行符。 使用简单的
<br/>
就可以了。 否则,你会看到一个白色的空间。 从浏览器查看源代码会告诉你真正发生了什么。 但是,有些情况下您期望这种行为,特别是如果消费者不是直接浏览器。 例如,您希望创build一个HTML页面,并在向浏览器提供空行和标识符之前查看其格式良好的结构。 - 记住你需要使用
disable-output-escaping
地方,以及你不需要的地方。 拿下面的例子来说,我必须从另外一个创build一个xml,并从样式表中声明它的DTD。
第一个版本确实会转义字符(默认为xsl:text)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes" encoding="utf-8"/> <xsl:template match="/"> <xsl:text><!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">


</xsl:text> <xsl:copy> <xsl:apply-templates select="*" mode="copy"/> </xsl:copy> </xsl:template> <xsl:template match="@*|node()" mode="copy"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="copy"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
这是结果:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"> <Subscriptions> <User id="1"/> </Subscriptions>
好吧,它做我们所期望的,转义完成,使我们使用的字符正确显示。 根节点中的XML部分格式化由ident="yes"
。 但仔细看,我们看到换行字符

没有被转义并翻译出来,执行了双重换行! 我对此没有一个解释,会很高兴知道。 任何人?
第二个版本不会逃避人物,所以他们正在生产他们的意思。 所做的改变是:
<xsl:text disable-output-escaping="yes"><!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">


</xsl:text>
这是结果:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"> <Subscriptions> <User id="1"/> </Subscriptions>
那样会好的 cr和lf都被正确渲染。
- 别忘了我们正在谈论
nl
,而不是crlf
(nl=lf
)。 我的第一个尝试是只使用cr:
,而输出xml被DOMvalidation正确。
我正在查看一个损坏的XML:
<?xml version="1.0" encoding="utf-8"?> <Subscriptions>riptions SYSTEM "Subscriptions.dtd"> <User id="1"/> </Subscriptions>
DOMparsing器忽略控制字符,但渲染没有。 我花了好一段时间,才意识到我没有看到这是多么愚蠢!
为了logging,我确实在CRLF中使用了一个variables,以确保它能在任何地方工作。
我第二个尼克·吉布森的方法,这总是我最喜欢的:
<xsl:variable name='nl'><xsl:text> </xsl:text></xsl:variable>
不过,我一直在使用Ant任务<echoxml>创build样式表,并针对文件运行它们。 该任务将执行属性值模板,例如$ {DSTAMP},但也将重新格式化您的XML,所以在某些情况下,实体引用是可取的。
<xsl:variable name='nl'><xsl:text>
</xsl:text></xsl:variable>
我不能只使用<xsl:text>
</xsl:text>
方法,因为如果使用XSLT格式化XML文件,实体将会消失。 所以我不得不使用variables稍微多一点的方法
<xsl:variable name="nl" select="' '"/> <xsl:template match="/"> <xsl:value-of select="$nl" disable-output-escaping="no"/> <xsl:apply-templates select="*"/> </xsl:template>
只需添加这个标签:
<br/>
它适用于我;)。