与元件替换XSLT版权符号和其它符号
<text>
Please see the registered mark® .
Please see the copy right ©.
Please see the Trade mark™.
</text>
输出:
<text>
Please see the registered mark<registeredTrademark></registeredTrademark>.
Please see the copy right <copyright></copyright>.
Please see the Trade mark <trademark></trademark>.
</text>
我需要更换与元素的所有特殊符号如上所示
可以在任何一个帮助。
感谢
该转化是通过避免炭通过炭递归和使用更有效的“最大可能步长”递归:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:reps>
<r char="®">registeredTrademark</r>
<r char="©">copyright</r>
<r char="™">trademark</r>
</my:reps>
<xsl:variable name="vReps" select="document('')/*/my:reps/*"/>
<xsl:template match="text()" name="multReplace">
<xsl:param name="pText" select="."/>
<xsl:param name="pReps" select="$vReps"/>
<xsl:if test="$pText">
<xsl:variable name="vTarget" select="$pReps[1]/@char"/>
<xsl:choose>
<xsl:when test="not($vTarget)">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vReplacement" select="$pReps[1]"/>
<xsl:call-template name="multReplace">
<xsl:with-param name="pText" select=
"substring-before(concat($pText, $vTarget), $vTarget)"/>
<xsl:with-param name="pReps" select="$pReps[position() >1]"/>
</xsl:call-template>
<xsl:if test="contains($pText, $vTarget)">
<xsl:element name="{$vReplacement}"/>
<xsl:call-template name="multReplace">
<xsl:with-param name="pText" select="substring-after($pText, $vTarget)"/>
<xsl:with-param name="pReps" select="$pReps"/>
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
当应用于提供的XML文档:
<text>
Please see the registered mark® .
Please see the copy right ©.
Please see the Trade mark™.
</text>
正确,替换文本,产生:
Please see the registered mark<registeredTrademark/> .
Please see the copy right <copyright/>.
Please see the Trade mark<trademark/>.
当我的XML有这些特殊字符时,我得到的错误为“给定编码中的无效字符”。有没有什么办法可以避免它 – Patan 2012-08-09 10:51:32
@ User222,你不是在说什么工具发布错误 - XML解析器,XSLT处理器或其他东西。所以很难建议如何避免这种不明的错误。我的猜测是某处(在你没有向我们显示的代码中),你指定/使用了默认编码,它没有这些字符。解决方案是指定utf-8作为编码(如果utf-8是默认值,则不指定任何内容)。 – 2012-08-09 12:00:59
谢谢你的回应。我的Visual Studio不支持此操作:( – Patan 2012-08-10 05:38:21
由于这是XSLT 1.0,你将不得不使用递归命名模板依次检查每个字符。
首先,它可能是更灵活地产生一种“查找”在你的XSLT,你可以指定符号列表和所需的元素名称与
<lookup:codes>
<code symbol="®">registeredTrademark</code>
<code symbol="©">copyright</code>
<code symbol="™">trademark</code>
</lookup:codes>
,以取代他们( 'lookup'命名空间实际上可以命名为任何东西,只要它在XSLT中是分层的即可)。
然后,访问此,您可以定义一个变量来访问该查询
<xsl:variable name="lookup" select="document('')/*/lookup:codes"/>
而且,为了查找基于符号实际的代码会做这样的事情(其中$文本)是一个包含正在检查的文本的变量。
<xsl:variable name="char" select="substring($text, 1, 1)"/>
<xsl:variable name="code" select="$lookup/code[@symbol = $char]"/>
所有命名模板要做的,就是检查文本的第一个字符,如果在查找存在与元素替换它,然后递归调用与文本的其余部分的模板。
以下是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:lookup="lookup" exclude-result-prefixes="lookup">
<xsl:output method="xml" indent="no"/>
<lookup:codes>
<code symbol="®">registeredTrademark</code>
<code symbol="©">copyright</code>
<code symbol="™">trademark</code>
</lookup:codes>
<xsl:variable name="lookup" select="document('')/*/lookup:codes"/>
<xsl:template match="text[text()]">
<text>
<xsl:call-template name="text"/>
</text>
</xsl:template>
<xsl:template name="text">
<xsl:param name="text" select="text()"/>
<xsl:variable name="char" select="substring($text, 1, 1)"/>
<xsl:variable name="code" select="$lookup/code[@symbol = $char]"/>
<xsl:choose>
<xsl:when test="$code"><xsl:element name="{$code}" /></xsl:when>
<xsl:otherwise>
<xsl:value-of select="$char"/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="string-length($text) > 1">
<xsl:call-template name="text">
<xsl:with-param name="text" select="substring($text, 2, string-length($text) - 1)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当施加到示例XML,下面是输出
<text>
Please see the registered mark<registeredTrademark /> .
Please see the copy right <copyright />.
Please see the Trade mark<trademark />.
</text>
是否有任何理由,你不能用一个简单的文本做更换XML来源? – Flynn1179 2012-08-08 10:20:28