问题描述
我有一个遵循此方案的 XML 文件:
I have a XML file following this scheme:
<translationData>
<product>
<attributeValue>
<value>1/4"</value>
<value1>1/4"</value1>
<currentValue>aaaa;bbbb</currentValue>
</attributeValue>
</product>
</translationData>
由于currentValue"中的分号,我需要转义分号和value"中的双引号.我可以通过将所有文本放在 qoutes 中来转义分号,如下所示:
because of the semicolon in "currentValue" i need to escape the semicolon AND the double quotes in "value".I am able to escape the semicolon by placing all text in qoutes as following:
XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8" />
<xsl:param name="delim" select="';'" />
<xsl:param name="quote" select="'"'" />
<xsl:param name="break" select="'
'" />
<xsl:template match="/">
<xsl:apply-templates select="translationData/product/attributeValue" />
</xsl:template>
<xsl:template match="attributeValue">
<xsl:apply-templates />
<xsl:if test="following::*">
<xsl:value-of select="$break" />
</xsl:if>
</xsl:template>
<xsl:template match="*">
<!-- remove normalize-space() if you want keep white-space at it is -->
<xsl:value-of select="concat($quote, translate(.,'"','\"'), $quote)" />
<xsl:if test="following-sibling::*">
<xsl:value-of select="$delim" />
</xsl:if>
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>
但不知何故输出是:
"1/4\";"1/4\";"aaaa;bbbb"
代替
"1/4\"";"1/4\"";"aaaa;bbbb"
我哪里出错了?
我是 XML 和 XSLT 的新手,在处理这个特定案例时没有发现任何问题.
I am new to XML and XSLT and did not find any question handling this specific case.
XSLT 代码来自@Tomalak 对另一个问题的回答.请参阅此处
XSLT code is from an answer by @Tomalak for another question. see here
推荐答案
translate()
函数只会用另一个单个字符替换每个单个字符.
The translate()
function will only replace each single character with another single character.
要将单个字符 "
替换为两个字符的字符串\"
,您需要使用命名递归模板或 - 如果您的处理器支持它 - 扩展功能例如 EXSLT str:replace().
To replace a single character "
with a two-character string\"
you need to use a named recursive template or - if your processor supports it - an extension function such as EXSLT str:replace().
以下是使用递归模板的示例:
Here's an example of using a recursive template:
...
<xsl:template match="*">
<xsl:text>"</xsl:text>
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
<xsl:text>"</xsl:text>
<xsl:if test="position()!=last()">
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:template>
...
<xsl:template name="replace">
<xsl:param name="text"/>
<xsl:param name="searchString">"</xsl:param>
<xsl:param name="replaceString">\"</xsl:param>
<xsl:choose>
<xsl:when test="contains($text,$searchString)">
<xsl:value-of select="substring-before($text,$searchString)"/>
<xsl:value-of select="$replaceString"/>
<!-- recursive call -->
<xsl:call-template name="replace">
<xsl:with-param name="text" select="substring-after($text,$searchString)"/>
<xsl:with-param name="searchString" select="$searchString"/>
<xsl:with-param name="replaceString" select="$replaceString"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
...
这篇关于XSLT 1.0:转义双引号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!