phl*_*opy 0 string xslt whitelist
使用XSLT 1.0,给定一个包含任意字符的字符串,如何找回符合以下规则的字符串.
在XSLT中,我将一些属性转换为元素,但我需要确保该属性不包含任何不能在元素名称中使用的值.我不关心转换为名称的属性的完整性,只要它被可预测地转换.我也不需要补偿元素名称中的每个有效字符(有一堆).
我遇到的问题是有空格的属性,translate函数可以很容易地转换为下划线:
translate(@name,' ','_')
Run Code Online (Sandbox Code Playgroud)
但是不久之后我发现了一些使用斜杠的属性,所以我现在也必须添加它.这很快就会失控.我希望能够定义允许字符的白名单,并用下划线替换任何不允许的字符,但翻译可以通过替换黑名单来实现.
您可以编写一个递归模板来执行此操作,逐个处理字符串中的字符,测试它们并在必要时更改它们.就像是:
<xsl:template name="normalizeName">
<xsl:param name="name" />
<xsl:param name="isFirst" select="true()" />
<xsl:if test="$name != ''">
<xsl:variable name="first" select="substring($name, 1, 1)" />
<xsl:variable name="rest" select="substring($name, 2)" />
<xsl:choose>
<xsl:when test="contains('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:_', $first) or
(not($first) and contains('0123456789.-', $first))">
<xsl:value-of select="$first" />
</xsl:when>
<xsl:otherwise>
<xsl:text>_</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="normalizeName">
<xsl:with-param name="name" select="$rest" />
<xsl:with-param name="isFirst" select="false()" />
</xsl:call-template>
</xsl:if>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
但是,如果你准备好了一些hackery,那么这样做的方法会更短.首先声明一些变量:
<xsl:variable name="underscores"
select="'_______________________________________________________'" />
<xsl:variable name="initialNameChars"
select="'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ:_'" />
<xsl:variable name="nameChars"
select="concat($initialNameChars, '0123456789.-')" />
Run Code Online (Sandbox Code Playgroud)
现在,该技术是取的名字和标识的人物不是由该名称替换所有字符的法律是合法的什么也没有.您可以使用该translate()功能执行此操作.一旦你获得了字符串中出现的非法字符集,就可以translate()再次使用该函数替换它们.这是模板:
<xsl:template name="normalizeName">
<xsl:param name="name" />
<xsl:variable name="first" select="substring($name, 1, 1)" />
<xsl:variable name="rest" select="substring($name, 2)" />
<xsl:variable name="illegalFirst"
select="translate($first, $initialNameChars, '')" />
<xsl:variable name="illegalRest"
select="translate($rest, $nameChars, '')" />
<xsl:value-of select="concat(translate($first, $illegalFirst, $underscores),
translate($rest, $illegalRest, $underscores))" />
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
您唯一需要注意的是,下划线字符串需要足够长以覆盖可能出现在单个名称中的所有非法字符.使它与您可能遇到的最长名称相同的长度将起到作用(尽管可能你可以侥幸使用它更短).