我的应用程序中有一个servlet过滤器,它拦截所有传入的请求,并尝试从传入的XML中删除空格,并将生成的“干净”XML写入响应。我正在使用XSLT来实现这一目标。请参阅下面的XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是,这没有按预期工作。生成的XML与原始XML相同(尽管在样式表中使用了&lt; xsl:strip-space elements =“*”/&gt ;.
请帮助我做到这一点。
的问候,
- Ashish
答案 0 :(得分:17)
目前尚不清楚您打算将其作为输出,以及您对xsl:strip-whitespace
的期望。但有一点需要注意的是,它不会删除所有空白,而只会删除那些在“通常”规则下被认为无关紧要的空白。特别是,来自XSLT 1.0规范:
除非文本节点仅包含空格字符,否则永远不会删除它。
所以,例如,这个:
<foo>
<bar> </bar>
</foo>
将被删除至:
<foo><bar/></foo>
因为它有3个仅限空格的文本节点(在<foo>
之后和<bar>
之前,在<bar>
和</bar>
之间,以及</bar>
之后和之前{ {1}})。
另请注意,由于样式表中包含</foo>
,因此最终会转换为:
<xsl:output indent="yes">
在输出中。
另一方面,这个:
<foo>
<bar/>
<foo>
根本不会被剥离,因为它包含的所有文本节点都不是纯粹的空白节点。
答案 1 :(得分:15)
使用原始问题中的xslt,<xsl:template match="text()"><xsl:value-of select="normalize-space(.)"/></xsl:template>
应该可以解决问题。
答案 2 :(得分:2)
将此作为第二个答案添加,因为第一个答案仍然(希望)提供足够的信息以保持它。
假设“trim”意味着“在打开之后和关闭标签之前立即删除所有空格”,那么以下额外的模板规则应该可以解决这个问题:
<xsl:variable name="whitespace"> 	
</xsl:variable>
<!-- Trim all whitespace at beginning of string -->
<xsl:template name="trim-start">
<xsl:param name="text"/>
<xsl:variable name="first-char" select="substring($text, 1, 1)" />
<xsl:choose>
<xsl:when test="contains($whitespace, $first-char)">
<xsl:call-template name="trim-start">
<xsl:with-param name="text" select="substring($text, 2)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Trim all whitespace at end of string -->
<xsl:template name="trim-end">
<xsl:param name="text"/>
<xsl:variable name="last-char" select="substring($text, string-length($text), 1)" />
<xsl:choose>
<xsl:when test="contains($whitespace, $last-char)">
<xsl:call-template name="trim-end">
<xsl:with-param name="text" select="substring($text, 1, string-length($text) - 1)" /> </xsl:call-template>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="text()">
<xsl:call-template name="trim-start">
<xsl:with-param name="text">
<xsl:call-template name="trim-end">
<xsl:with-param name="text" select=".">
</xsl:call-template>
<xsl:param>
</xsl:call-template>
</xsl:template>