xsl模板用自定义字符替换字符串的每个字符
xsl template to replace each character of string with a custom character
我有一个用例,我想用等于值长度的自定义字符转换 xml 键值。 Xml 我要转换的请求是:
<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 模板如
中所建议
现在我不想要静态 3 # 字符作为我的替换值。我不要。哈希的值等于键的值。
如果您使用 XSLT 2.0 或更高版本,您可以使用 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()
。不过,这有点老套,并且只会处理与第三个参数一样长的值...
<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 选项是使用递归模板调用...
<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>
所有这三个样式表,使用此输入:
<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>
我有一个用例,我想用等于值长度的自定义字符转换 xml 键值。 Xml 我要转换的请求是:
<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 模板如
现在我不想要静态 3 # 字符作为我的替换值。我不要。哈希的值等于键的值。
如果您使用 XSLT 2.0 或更高版本,您可以使用 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()
。不过,这有点老套,并且只会处理与第三个参数一样长的值...
<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 选项是使用递归模板调用...
<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>
所有这三个样式表,使用此输入:
<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>