如何在XSLT中插入 

231
我该如何在XSLT样式表中插入  ,我一直收到这个错误:

XML解析错误:未定义实体

本质上,我想在XSLT模板中使用一个不间断空格字符。

3
你也可以使用   来代替  。 在这里查看:https://dev59.com/qWs05IYBdhLWcg3wANPj - user3766111
13个回答

365
请使用实体代码 代替。  是HTML的“字符实体引用”。在XML中没有非断空格的命名实体,因此您需要使用代码 Wikipedia包括XML和HTML实体列表,您可以看到XML中只有5个“预定义实体”,但HTML有超过200个。我还会指向在XSL中创建空格( ),其中有很好的答案。

3
最近我们遇到了一个情况,其中有一个XSL文件使用这种技术时停止工作并显示出奇怪的字符。然而,如果我使用WaterSoul的CDATA技术,它就可以正常工作。 - user4903
@BrianReindel,这可能意味着您使用了错误的数字实体引用,即Š而不是 ,后者将始终解析为Unicode不间断空格。 - Abel
这个链接十大Java和XSLT技巧非常有用。 - LCJ
xsl:text </xsl:text> 用于分隔两个字段。 - Manash Ranjan Dakua
1
链接已经失效。 - GSerg

49

&#160;非常有效,但在ANSI编码中会显示一个奇怪的字符。<xsl:text>对我来说效果最好。


<xsl:text> </xsl:text>

3
使用被接受的答案后,我在XML输出中得到了一个断行空格(至少在VS2010的XML编辑器中是这样看的)。使用这个答案,我只得到了一个空格。 - Mathijs Flietstra
1
@Matthijs,这是一个空格,不是不换行空格(non-breaking space),它们不同。如果VS显示不正确,请检查编码(VS完全有能力正确显示它,而且应该与编码无关,所以更可能是你其他方面出了问题)。 - Abel

26

你还可以这样做:

<xsl:text disable-output-escaping="yes"><![CDATA[&nbsp;]]></xsl:text>

2
这将起作用如果处理器支持disable-output-escaping,但不是必需的,并且在XSLT 2.0中已被弃用,在3.0中更是如此。在这些版本中,您可以使用xsl:character-map实现相同的效果,保证跨处理器工作。此外,这会在输出中放置一个命名实体&nbsp;,它不一定与非断空格相同,接收端必须声明此实体(在HTML中通常是隐式的)。 - Abel

23

请使用此功能

<xsl:text disable-output-escaping="yes">&amp;</xsl:text>nbsp;

更新:投票者应该先验证此方法是否有效(事实上它是有效的,也是这个问题的最通用解决方案)。


1
不确定,但我已经测试了我的方法,它可以工作,所以我不确定为什么会被踩 :( - jagprinderdeep
2
另外,根据链接页面的说明,被接受的答案并非适用于所有解析器。提醒一下。 - jagprinderdeep
1
我之前已经解释了我为什么会给出负评的原因,但如果我要对这个答案进行负评,那么原因就是——它回答了错误的问题。楼主明确询问如何在使用XSLT时插入不间断空格,而你却回答了如何插入“ampersand-n-b-s-p-semicolon”序列。而且为了争论负评也不好。但说真的,你从未对CDATA说过这样的话吗? - Michael Krelin - hacker
8
我也给投了反对票,因为你无法保证接收方会声明。如果你正在使用xslt+html,那么是可以这样做的,尽管这是一种hack方法。但是,如果你正在使用xslt生成其他xml,则会出现问题。 - Doug
1
确认了@jagprinderdeep所说的不同之处:当我通过.Net 2使用我的XSL表格时,使用 实体会得到一个重音A。 - Liam Dawson
显示剩余6条评论

17

您可能希望在文件开头(xml声明下方)添加此实体的定义:

<!DOCTYPE stylesheet [
<!ENTITY nbsp  "&#160;" >
]>

除此之外,您还可以添加更多的实体,例如Ntilde、Aacute等。


6

除了维克多·雨果的答案之外,还可以通过以下方式获取在XSLT文件中所有已知的字符引用:

<!DOCTYPE stylesheet [
  <!ENTITY % w3centities-f PUBLIC "-//W3C//ENTITIES Combined Set//EN//XML"
      "http://www.w3.org/2003/entities/2007/w3centities-f.ent">
  %w3centities-f;
]>
...
<xsl:text>&amp; &nbsp; &ndash;</xsl:text>

这种方法的结果与使用<xsl:text disable-output-escaping="yes">的结果也有所不同。后者会为所有输出生成字符串文字,例如对于<xsl:output method="text">,甚至包括&nbsp;,这可能与您的意愿不同...相反,通过<!DOCTYPE ... <!ENTITY ...定义XSLT模板的实体将始终产生与您的xsl:output设置一致的输出。
当包含所有字符引用时,最好使用本地实体解析器,以防止XSLT引擎从Internet获取字符实体定义。 JAXP或显式的Xalan-J用户可能需要补丁才能正确使用解析器。请参见我的博客XSLT, entities, Java, Xalan...以下载补丁并发表评论。

1
请注意,最近W3开始阻止自动化进程从那些类似的链接中过多请求。将该文件放置在本地或服务器上并相应调整URL,您就可以安心使用了。除此之外,这是一个极佳的解决方案,使用HTML命名实体。加一赞! - Abel
一个好的注意事项,还有另一个原因需要在本地拷贝带有实体定义的文件,否则如果没有网络连接,XSLT处理过程很可能会失败。在Java世界中,无需破解URL,因为可以安排一个EntityResolver,而Apache XML Commons Resolver可能是一个不错的选择。其他编程平台也可能有类似的技术... - Sergey Ushakov
是的,所以对于.NET开发者的参考资料:ResolveEntity抽象方法用于实体和XmlResolver加载外部资源,这些是Java方法的.NET等效方法 - Abel

3

XSLT 样式表必须是格式良好的 XML。由于 "&nbsp;" 不属于 五个预定义的 XML 实体 之一,因此不能直接包含在样式表中。

因此,回到您的解决方案,"&#160;""&nbsp;" 的完美替代品,您应该使用它。

示例:

<xsl:value-of select="$txtFName"/>&#160;<xsl:value-of select="$txtLName"/>

2
当您使用以下内容(不使用disable-output-escaping!)时,您将获得一个单独的不间断空格:<xsl:text>&#160;</xsl:text>

4
您不需要使用 disable-output-escaping 来实现此功能。 - Ian Roberts

1

虽然@brabster和其他人已经提供了答案。
我认为更可重用的解决方案是:

<xsl:variable name="space">&#160;</xsl:variable>
...
<xsl:value-of select="$space"/>

0
尝试使用。
<xsl:text>&#160;</xsl:text>

但这取决于您使用的XSLT处理器:XSLT规范不要求XSLT处理器将其转换为 "&nbsp;"。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接