用自定义字符替换字符串的每个字符的 xsl 模板 [英] xsl template to replace each character of string with a custom character
问题描述
我有一个用例,我想用一个与值的长度等效的自定义字符来转换 xml 键值.我要转换的 XML 请求是:
I have a usecase where I want to transform the xml key value with a custom character equivalent to the length of the value. Xml request that I want to transform is :
<root>
<entries>
<entry>
<key>key1</key>
<value>value1</value>
</entry>
<entry>
<key>key2</key>
<value>value2</value>
</entry>
<entry>
<key>key3</key>
<value>value3</value>
</entry>
</entries>
</root>
我用来将特定键值转换为自定义值的当前 xml 模板如 寻找以键值标签形式屏蔽xml内容的实用程序
Current xml template I am using to covert the specific key values to custom values is as suggested in Looking for a utility to mask xml content in form of key value tags
现在我不想要静态 3 # 字符作为我的替换值.我不要.哈希值等于键的值.
Now I dont want static 3 # character as my replacement value. I want no. of hash to be equivalent to the value of the key.
推荐答案
如果您使用的是 XSLT 2.0 或更高版本,您可以使用 replace()
...
If you're using XSLT 2.0 or above, you can use replace()
...
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="keys" select="'key1','key2','key3'"/>
<xsl:param name="char" select="'#'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="entry[key=$keys]/value/text()">
<xsl:value-of select="replace(.,'.',$char)"/>
</xsl:template>
</xsl:stylesheet>
如果您使用 XSLT 1.0,您可以使用带有长第三个参数的 translate()
.虽然这有点hacky,并且只会处理与第三个参数一样的值......
If you're using XSLT 1.0, you could use translate()
with a long third argument. This is kinda hacky though and would only handle values as long as the third argument...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="keys" select="'|key1|key2|key3|'"/>
<xsl:param name="mask"
select="'###################################################################'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="value/text()">
<xsl:choose>
<xsl:when test="contains($keys,concat('|',../../key,'|'))">
<xsl:value-of select="translate(.,.,$mask)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
更好的 XSLT 1.0 选项是使用递归模板调用...
A better XSLT 1.0 option is to use a recursive template call...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="keys" select="'|key1|key2|key3|'"/>
<xsl:param name="char" select="'#'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="value/text()" name="mask">
<xsl:param name="input" select="."/>
<xsl:variable name="toMask" select="substring($input,2)"/>
<xsl:choose>
<xsl:when test="contains($keys,concat('|',../../key,'|'))">
<xsl:value-of select="$char"/>
<xsl:if test="string($toMask)">
<xsl:call-template name="mask">
<xsl:with-param name="input" select="$toMask"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
所有这三个样式表,使用这个输入:
All three of these stylesheets, using this input:
<root>
<entries>
<entry>
<key>key1</key>
<value>value1</value>
</entry>
<entry>
<key>key2</key>
<value>value222222</value>
</entry>
<entry>
<key>key3</key>
<value></value>
</entry>
<entry>
<key>key4</key>
<value>leave me alone</value>
</entry>
</entries>
</root>
将输出:
<root>
<entries>
<entry>
<key>key1</key>
<value>######</value>
</entry>
<entry>
<key>key2</key>
<value>###########</value>
</entry>
<entry>
<key>key3</key>
<value/>
</entry>
<entry>
<key>key4</key>
<value>leave me alone</value>
</entry>
</entries>
</root>
这篇关于用自定义字符替换字符串的每个字符的 xsl 模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!