输入:
<Data>
<info>the %text ^with *special chars asxbajx @ fagfa ~</info>
</Data>
输出:
<Data>
<info> the ++text ++with ++special chars asxbajx ++ fagfa ++</info>
</Data>
要求:
搜索一些特定的字符集,并将其替换为文本“++”。如果遇到charecter需要向用户显示消息。
XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="aaa">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<my:pNames>
<n>%</n>
<n>^</n>
<n>*</n>
<n>@</n>
<n>~</n>
</my:pNames>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:param name="pText" select="."/>
<xsl:for-each select="document('')/*/my:pNames/n">
<xsl:variable name="testvar1" select="."/>
<xsl:if test="contains($pText,$testvar1)">
<xsl:message terminate="no">
<xsl:value-of select="$pText"/>
</xsl:message>
</xsl:if>
</xsl:for-each>
<xsl:variable name="testvar" select="document('')/*/my:pNames"/>
<xsl:value-of select="
translate(
.,
$testvar,
'+'
)
"/>
</xsl:template>
</xsl:stylesheet>
我没有得到确切的输出。
任何人都可以帮助我。
答案 0 :(得分:0)
您遇到的第一个问题是翻译功能仅将“单个字符”翻译成另一个字符。所以你不能用它来用双字符串%
替换单个字符++
。此外,您通常具有相同长度的第二个和第三个参数
translate(., '%^*@~', '+++++')
这是因为'from'字符被'to'字符串中相应位置的字符替换。如果你只是翻译(。,'%^ * @〜','+'),那么字符^*@~
将被替换为什么!
XSLT1.0没有替换功能(虽然存在于XSTL2.0中),因此首先需要搜索递归模板来完成这项工作。这是一个!
<xsl:template name="string-replace-all">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
不是依次为每个参数调用它,而是首先可以使用translate函数将所有有趣的字符替换为一个有趣的字符(例如,%
)
首先定义一个变量来保存第一个字符参数
<xsl:variable name="firstchar" select="document('')/*/my:pNames/n[1]" />
然后定义两个变量,如此
<xsl:variable name="testvar">
<xsl:apply-templates select="document('')/*/my:pNames/n" mode="replace"/>
</xsl:variable>
<xsl:variable name="replace">
<xsl:apply-templates select="document('')/*/my:pNames/n" mode="by"/>
</xsl:variable>
相应的模板看起来像这样
<xsl:template match="my:pNames/n" mode="replace">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="my:pNames/n" mode="by">
<xsl:value-of select="$firstchar"/>
</xsl:template>
这意味着 testvar 变量将设置为%^*@~
,替换将设置为+++++
。然后,您可以使用翻译功能将所有有趣角色的出现替换为相同的角色
translate(., $testvar, $replace)
这意味着您只需要调用替换模板一次
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="translate(., $testvar, $replace)" />
<xsl:with-param name="replace" select="$firstchar" />
<xsl:with-param name="by" select="'++'" />
</xsl:call-template>
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="aaa">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<my:pNames>
<n>%</n>
<n>^</n>
<n>*</n>
<n>@</n>
<n>~</n>
</my:pNames>
<xsl:variable name="firstchar" select="document('')/*/my:pNames/n[1]" />
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:param name="pText" select="."/>
<xsl:for-each select="document('')/*/my:pNames/n">
<xsl:variable name="testvar1" select="."/>
<xsl:if test="contains($pText,$testvar1)">
<xsl:message terminate="no">
<xsl:value-of select="$pText"/>
</xsl:message>
</xsl:if>
</xsl:for-each>
<xsl:variable name="testvar">
<xsl:apply-templates select="document('')/*/my:pNames/n" mode="replace"/>
</xsl:variable>
<xsl:variable name="replace">
<xsl:apply-templates select="document('')/*/my:pNames/n" mode="by"/>
</xsl:variable>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="translate(., $testvar, $replace)" />
<xsl:with-param name="replace" select="$firstchar" />
<xsl:with-param name="by" select="'++'" />
</xsl:call-template>
</xsl:template>
<xsl:template match="my:pNames/n" mode="replace">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="my:pNames/n" mode="by">
<xsl:value-of select="$firstchar"/>
</xsl:template>
<xsl:template name="string-replace-all">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="by"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$by"/>
<xsl:call-template name="string-replace-all">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="by" select="$by"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当应用于输入XML时,输出以下内容
<Data>
<info>the ++text ++with ++special chars asxbajx ++ fagfa ++</info>
</Data>