从使用 XSL 生成的 HTML 中删除空格
Posted
技术标签:
【中文标题】从使用 XSL 生成的 HTML 中删除空格【英文标题】:Remove whitespace from HTML generated using XSL 【发布时间】:2012-05-21 12:44:53 【问题描述】:背景
在生成 html 时保持可读的 XSL 源代码,避免在句子及其终止标点符号之间引入空格的过多中断。来自Rethinking XSLT:
XSLT 样式表中的空白尤其成问题,因为它有两个用途:(1) 格式化 XSLT 样式表本身; (2) 用于指定 XSLT 处理的 XML 数据的输出中的空白位置。
问题
XSL 模板包含以下代码:
<xsl:if test="@min-time < @max-time">
for
<xsl:value-of select="@min-time" />
to
<xsl:value-of select="@max-time" />
minutes
</xsl:if>
<xsl:if test="@setting">
on <xsl:value-of select="@setting" /> heat
</xsl:if>
.
例如,这会生成以下输出(空格完全如图所示):
for
2
to
3
minutes
.
所有主流浏览器都产生:
for 2 to 3 minutes .
几乎完美无缺,除了单词minutes
和标点符号之间的空格。所需的输出是:
for 2 to 3 minutes.
可以通过删除 XSL 模板中的缩进和换行来消除空格,但这意味着 XSL 源代码很难看。
解决方法
最初所需的输出被包装在一个变量中,然后写出如下:
<xsl:value-of select="normalize-space($step)" />.
这一直有效,直到我尝试将 <span>
元素包装到变量中。 <span>
元素从未出现在生成的 HTML 代码中。以下代码也不正确:
<xsl:copy-of select="normalize-space($step)" />.
技术细节
样式表已经使用:
<xsl:strip-space elements="*" />
<xsl:output indent="no" ... />
相关
Storing html tags within an xsl variable问题
您如何告诉 XSLT 处理器消除该空间?
谢谢!
【问题讨论】:
您是否尝试过使用virtual formatting 编辑器?有了这个,首先不会向源代码添加缩进字符 - 格式化只是在编辑 XSLT 时不断回流到 XSLT 上下文。 @pgfearo:我太依赖vi
。 ;-) 我已经用一个额外的变量解决了这个问题。不过,谢谢你的想法!
【参考方案1】:
除了使用copy-of
,您还可以将标识模板与一个额外的模板一起应用,该模板从文本节点中修剪空间。您只需像在第一个解决方法中一样创建一个变量。
你打电话:
<li><xsl:apply-templates select="$step" mode="nospace" />.</li>
模板:
<xsl:template match="text()" mode="nospace" priority="1" >
<xsl:value-of select="normalize-space(.)" />
</xsl:template>
<xsl:template match="node() | @*" mode="nospace">
<xsl:copy>
<xsl:apply-templates select="node() | @*" mode="nospace" />
</xsl:copy>
</xsl:template>
【讨论】:
【参考方案2】:我。这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="t[@max-time > @min-time]">
<span>
<xsl:value-of select=
"concat('for ', @min-time, ' to ', @max-time, ' minutes')"/>
</span>
<xsl:apply-templates select="@setting"/>
<xsl:text>.</xsl:text>
</xsl:template>
<xsl:template match="@setting">
<span>
<xsl:value-of select="concat(' on ', ., ' heat')"/>
</span>
</xsl:template>
</xsl:stylesheet>
应用于以下 XML 文档时(没有出现过!):
<t min-time="2" max-time="3" setting="moderate"/>
产生想要的正确结果:
<span>for 2 to 3 minutes</span>
<span> on moderate heat</span>.
它被浏览器显示为:
2 到 3 分钟 中等热量。
当对这个 XML 文档应用相同的转换时:
<t min-time="2" max-time="3"/>
再次产生正确的、想要的结果:
<span>for 2 to 3 minutes</span>.
它被浏览器显示为:
2 到 3 分钟。
二。布局(视觉)解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" xmlns:gen="gen:gen" xmlns:gen-attr="gen:gen-attr"
exclude-result-prefixes="my gen">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:layout>
<span>for <gen-attr:min-time/> to <gen-attr:max-time/> minutes</span>
<gen-attr:setting><span> on <gen:current/> heat</span></gen-attr:setting>
<gen:literal>.</gen:literal>
</my:layout>
<xsl:variable name="vLayout" select="document('')/*/my:layout/*"/>
<xsl:variable name="vDoc" select="/"/>
<xsl:template match="node()|@*">
<xsl:param name="pCurrent"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pCurrent" select="$pCurrent"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$vLayout">
<xsl:with-param name="pCurrent" select="$vDoc/*"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="gen-attr:*">
<xsl:param name="pCurrent"/>
<xsl:value-of select="$pCurrent/@*[name() = local-name(current())]"/>
</xsl:template>
<xsl:template match="gen-attr:setting">
<xsl:param name="pCurrent"/>
<xsl:variable name="vnextCurrent" select=
"$pCurrent/@*[name() = local-name(current())]"/>
<xsl:apply-templates select="node()[$vnextCurrent]">
<xsl:with-param name="pCurrent" select="$vnextCurrent"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="gen:current">
<xsl:param name="pCurrent"/>
<xsl:value-of select="$pCurrent"/>
</xsl:template>
<xsl:template match="gen:literal">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
这种转换让我们了解如何对所需输出进行可视化(骨架)表示,并使用它从源 XML 文档中“填充”所需数据。
结果与第一个解决方案的结果相同。如果这种转换“按原样”运行,它将产生大量命名空间——它们是无害的,并且如果布局位于单独的 XML 文件中,则不会产生。
【讨论】:
@DaveJarvis:我们无法猜测——我已经回答了你提供的问题。您可以使用缺少的信息编辑问题,或者(首选)提出新问题。我可以向您保证,适当地使用 XSLT 可以产生想要的结果——通常不需要后处理。在我提供的第二个解决方案中,我展示了“填空”的想法,它既直观又强大。总而言之:凭借良好的设计和适当的 XSLT 专业知识,可以成功轻松地解决此问题和类似问题。以上是关于从使用 XSL 生成的 HTML 中删除空格的主要内容,如果未能解决你的问题,请参考以下文章
使用 XSLT 将 XML 转换为 XML 删除前导空格和零
从整个 Html 中删除空格,但在 pre 中使用正则表达式