XSLT 多重替换 [英] XSLT multiple replacing
问题描述
我有一个 XML 文档,类似于
I have an XML document, something like
<root>
<item>_x0034_SOME TEXT</item>
<item>SOME_x0020_TEXT</item>
<item>SOME_x0020_TEXT_x0032_</item>
</root>
我将其导出为 HTML,但在替换转义字符时遇到问题.我在网上找到了几个模板来进行文本替换,但它们都与此类似:
I'm exporting it to HTML, but I have problems replacing escape characters. I have found several templates in the web to do text replacing but they all are similar to this:
<xsl:template name="replaceString">
<xsl:param name="strOrig"/>
<xsl:param name="strSearch"/>
<xsl:param name="strReplace"/>
<xsl:choose>
<xsl:when test="contains($strOrig, $strSearch)">
<xsl:value-of select="substring-before($strOrig, $strSearch)"/>
<xsl:value-of select="$strReplace"/>
<xsl:call-template name="replaceString">
<xsl:with-param name="strOrig" select="substring-after($strOrig, $strSearch)"/>
<xsl:with-param name="strSearch" select="$strSearch"/>
<xsl:with-param name="strReplace" select="$strReplace"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$strOrig"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
我不确定如何使用它来进行多次替换.我试过这个:
I'm not sure how I can use this to do the multiple replacements. I have tried this:
<xsl:for-each select="PinnacleSys.PMC.Plugins.PVR.PvrChannelDescriptorWrapper/PinnacleSys.PMC.Plugins.PVR.DVBTPvrChannelDescriptor">
<!--name="<xsl:value-of select="replace(replace(Name, '_x0020_', ' '), '_x0034_', '3')"/>" -->
<!--name="<xsl:value-of select="Name"/>"-->
<xsl:variable name="var1" select="Text" />
<xsl:value-of select="replace($FeatureInfo,'Feature=','TESTING')"/>
name="
<xsl:call-template name="replaceString">
<xsl:with-param name="strOrig" select="Name"/>
<xsl:with-param name="strSearch" select="'_x0020_'"/>
<xsl:with-param name="strReplace" select="' '"/>
</xsl:call-template>
<xsl:call-template name="replaceString">
<xsl:with-param name="strOrig" select="Name"/>
<xsl:with-param name="strSearch" select="'_x0030_'"/>
<xsl:with-param name="strReplace" select="'0'"/>
</xsl:call-template>
..."
但这只是将字符串连接了几次,每次都有不同的替换.我还研究了变量;如果我可以将模板调用的结果分配给一个变量,我可以获得一个脏但有效的解决方案,这对我来说已经足够了.但是我没能,也不知道是否有可能.
But this just concatenates the string several times, each with a different replacement. I have also investigated variables; if I could assign the result of a template call to a variable, I could get a dirty-but-works solution, which is enough for me. However I haven't been able and don't know if it's possible.
最好的方法是什么?
我只能使用 1.0 XSLT(使用 2.0 我可以在另一个内部调用一个 replace()).
I'm restricted to 1.0 XSLT (with 2.0 I could call one replace() inside another).
推荐答案
对于使用模板进行替换的本机 XSLT 1.0 解决方案,需要嵌套各个替换,如下所示.由于潜在的替换次数,这显然效率不高.优化后的版本如下.
For a native XSLT 1.0 solution using a template for replacement, the individual replacements need to be nested, as shown here. This obviously isn't efficient due to the potential number of replacements. An optimized version is given below.
<xsl:template match="item">
<xsl:copy>
<xsl:call-template name="replace-substring">
<xsl:with-param name="original">
<xsl:call-template name="replace-substring">
<xsl:with-param name="original">
<xsl:call-template name="replace-substring">
<xsl:with-param name="original" select="."/>
<xsl:with-param name="substring" select="'_x0020_'"/>
<xsl:with-param name="replacement" select="' '"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="substring" select="'_x0032_'"/>
<xsl:with-param name="replacement" select="'2'"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="substring" select="'_x0034_'"/>
<xsl:with-param name="replacement" select="'4'"/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="replace-substring">
<xsl:param name="original"/>
<xsl:param name="substring"/>
<xsl:param name="replacement" select="''"/>
<xsl:choose>
<xsl:when test="contains($original, $substring)">
<xsl:value-of select="substring-before($original, $substring)"/>
<xsl:copy-of select="$replacement"/>
<xsl:call-template name="replace-substring">
<xsl:with-param name="original" select="substring-after($original, $substring)"/>
<xsl:with-param name="substring" select="$substring"/>
<xsl:with-param name="replacement" select="$replacement"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$original"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
由于输出是 HTML(XML 也可以),_xNNNN_
字符串可以转换为其十六进制数字字符引用,例如 &#xNNNN;
.这个模板很有效.
Since the output is HTML (XML would be fine too), the _xNNNN_
strings can be converted to their hex numeric character references, e.g., &#xNNNN;
. This template is efficient.
<xsl:template match="item">
<xsl:copy>
<xsl:call-template name="replaceChars">
<xsl:with-param name="original" select="."/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="replaceChars">
<xsl:param name="original"/>
<xsl:choose>
<xsl:when test="contains($original, '_x')">
<xsl:value-of select="substring-before($original, '_x')"/>
<xsl:variable name="after" select="substring-after($original, '_x')"/>
<xsl:variable name="char" select="substring-before($after, '_')"/>
<xsl:value-of select="concat('&#x',$char,';')" disable-output-escaping="yes"/>
<xsl:call-template name="replaceChars">
<xsl:with-param name="original" select="substring-after($after, '_')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$original"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
这是结果输出.
<root>
<item>4SOME TEXT</item>
<item>SOME TEXT</item>
<item>SOME TEXT2</item>
</root>
这篇关于XSLT 多重替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!