在XSLT中生成一个新行

我想为XSLT中的文本输出生成一个换行符。 有任何想法吗?

以下XSL代码将生成换行符 ( 换行符 ):

<xsl:text>&#xa;</xsl:text> 

对于回车 ,请使用:

 <xsl:text>&#xd;</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的源代码整洁,请使用实体&#10; 你想要一个新的线路。

您可以使用: <xsl:text>&#10;</xsl:text>

看到这个例子

 <xsl:variable name="module-info"> <xsl:value-of select="@name" /> = <xsl:value-of select="@rev" /> <xsl:text>&#10;</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>字面换行符和使用&#xA;

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

更改为实体( &#xA; )使我的文件生成代码在Java和.NET上运行一致。

另外,文字换行符很容易被IDE重新格式化,并且当文件被不知情的人维护时可能会不经意间丢失。

我添加了你在这里看到的DOCTYPE指令:

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY nl "&#xa;"> ]> <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; 而不是&#xa; 在输出中产生一个换行符。 与其他解决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/>&#xa (hex)或者&#10 (十进制)将始终有效,但是您可能看不到它。

  1. HTML标记中没有换行符。 使用简单的<br/>就可以了。 否则,你会看到一个白色的空间。 从浏览器查看源代码会告诉你真正发生了什么。 但是,有些情况下您期望这种行为,特别是如果消费者不是直接浏览器。 例如,您希望创build一个HTML页面,并在向浏览器提供空行和标识符之前查看其格式良好的结构。
  2. 记住你需要使用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>&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</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"?> &lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt; &#13;<Subscriptions> <User id="1"/> </Subscriptions> 

好吧,它做我们所期望的,转义完成,使我们使用的字符正确显示。 根节点中的XML部分格式化由ident="yes"但仔细看,我们看到换行字符&#xa没有被转义并翻译出来,执行了双重换行! 我对此没有一个解释,会很高兴知道。 任何人?

第二个版本不会逃避人物,所以他们正在生产他们的意思。 所做的改变是:

 <xsl:text disable-output-escaping="yes">&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text> 

这是结果:

 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"> <Subscriptions> <User id="1"/> </Subscriptions> 

那样会好的 cr和lf都被正确渲染。

  1. 别忘了我们正在谈论nl ,而不是crlfnl=lf )。 我的第一个尝试是只使用cr: &#xd ,而输出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>&#xa;</xsl:text></xsl:variable> 

我不能只使用<xsl:text>&#xa;</xsl:text>方法,因为如果使用XSLT格式化XML文件,实体将会消失。 所以我不得不使用variables稍微多一点的方法

 <xsl:variable name="nl" select="'&#10;'"/> <xsl:template match="/"> <xsl:value-of select="$nl" disable-output-escaping="no"/> <xsl:apply-templates select="*"/> </xsl:template> 

只需添加这个标签:

 <br/> 

它适用于我;)。