如何强制逃避每一个双引号"进入XML角色实体"

时间:2015-09-24 15:25:58

标签: xml xslt escaping xslt-1.0 soa

如何将字符串中的所有"转换为"

示例:

来源数据: <String>"ACCOUNT_DETAILS" : "75"</String>

目标数据: <String>&quot;ACCOUNT_DETAILS&quot; : &quot;75&quot;</String>

PS:我正在使用XSLT 1.0。我试过&#34; XSLT string replace&#34;但它没有用。

2 个答案:

答案 0 :(得分:3)

你为什么要做这样的事情?从XML的角度来看,&quot; "完全相同。任何XSLT处理器(或者就此而言的XML库)都会正确地转义单引号和双引号,当它们在属性中显示为文字时,这通常是他们需要转义为&apos;和{{1}的唯一地方分别。

但是,如果有一些奇怪的要求你必须这样做(有很多工具只支持部分XML或其某些变体),你可以执行以下操作:

&quot;

将输出<xsl:text disable-output-escaping="yes">&amp;quot;</xsl:text> 。请注意,处理器不需要支持&quot;,即使它确实如此,它也不必遵守,而从XSLT 2.0开始,您应该使用disable-output-escaping代替,这是一个更好的更灵活的替代方案。

使用XSLT 1.0的字符串替换模板

您可能已经跟进的问题是如何将此技术应用于整个字符串。由于XSLT 1.0没有良好的字符串搜索和替换功能,因此必须使用递归调用模板。对于练习(我对XSLT 1.0有点生疏,并且通常使用XSLT 2.0或更高版本,其中这是一个单行),我想我会再次尝试它为旧时的缘故。

这适用于您的输入:

xsl:character-map

和输出:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:variable name="input">"ACCOUNT_DETAILS" : "75"</xsl:variable>

    <xsl:template match="/">
        <xsl:variable name="result">
            <xsl:call-template name="replace">
                <xsl:with-param name="string" select="$input"/>
                <xsl:with-param name="search" select="'&quot;'" />
                <xsl:with-param name="replace-with" select="'&amp;quot;'" />
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$result" disable-output-escaping="yes" />
    </xsl:template>

    <xsl:template name="replace">
        <xsl:param name="string" />
        <xsl:param name="search" />
        <xsl:param name="replace-with" />        
        <xsl:choose>
            <xsl:when test="contains($string, $search)">
                <xsl:value-of select="substring-before($string, $search)" />
                <xsl:value-of select="$replace-with" />
                <xsl:call-template name="replace">
                    <xsl:with-param name="string" select="substring-after($string, $search)" />
                    <xsl:with-param name="search" select="$search" />
                    <xsl:with-param name="replace-with" select="$replace-with" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$string" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

编辑:使用JSON转义&quot;ACCOUNT_DETAILS&quot; : &quot;75&quot;

在你写的评论中,你需要这个用于JSON。使用JSON转义可能更容易,因为它们在XML中没有特殊含义。

按照上面的代码调用,如下所示,然后删除\"

disable-output-escaping

或者,如果你想要XML样式的转义,而不是字面地将<xsl:call-template name="replace"> <xsl:with-param name="string" select="$input"/> <xsl:with-param name="search" select="'&quot;'" /> <xsl:with-param name="replace-with" select="'\&quot;'" /> </xsl:call-template> 写入输出流(这只是编写&quot;的另一种方式,并且将被任何XML解析器解释为)您可以使用上面相同的代码双重转义引号,但没有"。然后,文字XML将包含disable-output-escaping,您的浏览器或XML解析器会将其视为&amp;quot(在取消后)。

答案 1 :(得分:2)

我认为在XSLT 2.0中应该可以使用字符映射:http://xsltransform.net/pPzifoT/1。使用XSLT 1.0,您可以使用命名模板替换双引号<xsl:text disable-output-escaping="yes"><![CDATA[&quot;]]></xsl:text>