如何用空格替换字符串中的所有特殊字符



我使用的是XSLT1.0。

假设我有一个类似于"apple mango%also | there"的字符串

我正在尝试用空格替换所有非字母数字字符。我试过

<xsl:value-of select="translate(., translate(., '0123456789abcdefghijklmnopqrstuvwxysABCDEFGHIJKLMNOPQRSTUVWXYZ', ''), ' ')"/>

但没有奏效。问题在于外部翻译。

据我所知,在translate()中,第三个字符串的长度应该与第二个字符串的相同,否则丢失的字符将被空字符串('')取代。

内部翻译工作得很好,因为我无论如何都想删除所有带有空字符串的字符。

但外部翻译只将第二个参数字符串的第一个字符替换为空格,将其余字符替换为空字符串。

由于外部翻译的第二个参数中的非字母数字字符列表是动态的,所以我无法对第三个参数进行预编码。

例如:

我的内部翻译将返回-%|。这是正确的。

现在我的外译是translate(., '-%|', ' ')

返回apple mangoalsothere

如果不写这样的东西,怎么能做到呢:

translate(., '`~!@#$%^&*()-_=+[]{}|;:'",<.>/?', '                                  ')

另一种方法是使用"内部翻译"的结果(即包含所有不需要的字符的字符串)作为命名递归模板中的参数,该模板将用空格一个接一个地替换它们:

XML

<input>alpha-bravo/charlie#delta...echo?foxtrot%golf|hotel india-juliet</input>

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:template match="/">
<output>
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="input"/>
<xsl:with-param name="delimiters" select="translate(input, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '')"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="string"/>
<xsl:param name="delimiters"/>
<xsl:choose>
<xsl:when test="$delimiters">
<xsl:variable name="delimiter" select="substring($delimiters, 1, 1)" /> 
<xsl:value-of select="substring-before($string, $delimiter)" />
<xsl:text> </xsl:text>
<!-- recursive call -->
<xsl:call-template name="tokenize">
<xsl:with-param name="string" select="substring-after($string, $delimiter)"/>
<xsl:with-param name="delimiters" select="substring($delimiters, 2)"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

结果

<?xml version="1.0" encoding="utf-8"?>
<output>alpha bravo charlie delta   echo foxtrot golf hotel india juliet</output>

实现这一点的一种方法是创建一个递归模板,为给定长度的创建一个只有空格的字符串

<xsl:template name="AllSpaces">
<xsl:param name="spaces" />
<xsl:if test="$spaces > 0">
<xsl:text> </xsl:text>
<xsl:call-template name="AllSpaces">
<xsl:with-param name="spaces" select="$spaces - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>

然后,您可以生成一个字符串,其空格数等于正在处理的字符串的长度。

<xsl:variable name="specialchars" select="translate(., '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '')" />
<xsl:variable name="spaces">
<xsl:call-template name="AllSpaces">
<xsl:with-param name="spaces" select="string-length($specialchars)" />
</xsl:call-template>
</xsl:variable>

然后,您可以在翻译中使用这个spaces变量。例如,试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:template match="data">
<xsl:variable name="specialchars" select="translate(., '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', '')" />
<xsl:variable name="spaces">
<xsl:call-template name="AllSpaces">
<xsl:with-param name="spaces" select="string-length($specialchars)" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="translate(., $specialchars, $spaces)"/>
</xsl:template>
<xsl:template name="AllSpaces">
<xsl:param name="spaces" />
<xsl:if test="$spaces > 0">
<xsl:text> </xsl:text>
<xsl:call-template name="AllSpaces">
<xsl:with-param name="spaces" select="$spaces - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

现在,如果您在XML中有多个要替换的字符串,那么可以通过为spaces设置一个全局变量来稍微改进,该变量等于最长字符串的长度。这会给你更多的空间,但这不是问题。

也试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:variable name="spaces">
<xsl:for-each select="//data">
<xsl:sort select="string-length(.)" order="descending" />
<xsl:if test="position() = 1">
<xsl:call-template name="AllSpaces">
<xsl:with-param name="spaces" select="string-length(.)" />
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="data">
<xsl:value-of select="translate(., translate(., '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ''), $spaces)"/>
</xsl:template>
<xsl:template name="AllSpaces">
<xsl:param name="spaces" />
<xsl:if test="$spaces > 0">
<xsl:text> </xsl:text>
<xsl:call-template name="AllSpaces">
<xsl:with-param name="spaces" select="$spaces - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

应用于此XML 时

<test>
<data>apple-mango%also|there</data>
<data>apple-mango%also|there!test</data>
</test>

以下是输出

apple mango also there
apple mango also there test

相关内容

  • 没有找到相关文章

最新更新