使用 xsltproc 转义 XML 属性的值

Posted

技术标签:

【中文标题】使用 xsltproc 转义 XML 属性的值【英文标题】:Escaping value of XML attribute with xsltproc 【发布时间】:2013-04-20 19:18:26 【问题描述】:

使用 xsltproc (XSLT 1.0) 我试图从 xsl-value @name 属性中转义(“-> 到 \”)内容。

XSL:

<xsl:template match="int:signature">
    "name":"<xsl:value-of select="@name" mode="text"/>",
    ....

原始 XML:

<signature name="My &quot;case&quot;" />

输出:

 "name":"My "case"",

这会破坏生成的 JSON

我尝试使用 str:replace 没有成功。 disable-output-escaping="yes" 也没有成功。

有什么提示吗?

--

xsltproc -V

使用 libxml 20706、libxslt 10126 和 libexslt 815

【问题讨论】:

请添加一个带有您预期输出(也可能是输入)的示例:喊这个是"name":"xxxxx"\"name":\"xxxxx\"。还是应该改一下@name的内容? 我对解释做了一些改进。是的,@name 的内容应该被改变(被转义)。 xslt 1.0 的一种可能性是使用递归模板调用来转义引号。但是,将外在的引号改为撇号还不够吗? "name":My "case"´,`(这应该是有效的 jason) 【参考方案1】:

如果你需要逃避这样的事情会有所帮助

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space  elements="*"/>
    <xsl:template match ="signature">
        <xsl:variable name="escape">
            <xsl:call-template name="escape_quot">
                <xsl:with-param name="replace" select="@name"/>
            </xsl:call-template>
        </xsl:variable>
        "name":"<xsl:value-of select="$escape" />",
    </xsl:template>

    <xsl:template name="escape_quot">
        <xsl:param name="replace"/>
        <xsl:choose>
            <xsl:when test="contains($replace,'&quot;')">
                <xsl:value-of select="substring-before($replace,'&quot;')"/>
                <!-- escape quot-->
                <xsl:text>\"</xsl:text> 
                <xsl:call-template name="escape_quot">
                    <xsl:with-param name="replace" select="substring-after($replace,'&quot;')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$replace"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

这将生成常用的输出。

 "name":"My \"case\"",

更新: 但是,将外在的引号改为撇号还不够吗?

与:

 "name":'<xsl:value-of select="@name" />',

得到:

  "name":'My "case"',

(这应该是有效的 JSON)

【讨论】:

如果我改为 "name":'..' 我想我需要关心 ' 而不是 " 我猜,因为某些参数值可能包含该字符。【参考方案2】:

这适用于 XPath 2.0

"name":"<xsl:value-of select='fn:replace(@name, """", "\\""")' />"

据我所知,xsltproc 不支持 Xpath 2.0,但也许 EXSLT 扩展提供相同的功能

【讨论】:

使用 xsltproc:"name":"&lt;xsl:value-of select='str:replace(@name, """", "\\""")' /&gt;", 我收到此错误:XPath error : Invalid expression str:replace(@name, """", "\\""") ^ compilation error: file interproscan.xsl line 132 element value-of xsl:value-of : could not compile select expression 'str:replace(@name, """", "\\""")'

以上是关于使用 xsltproc 转义 XML 属性的值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 xsltproc 将 XML 缩进四个空格?

XSLT 1.0 (xsltproc) - 无法解析巨大的 XML

如何使用带有样式表和 xsltproc 的 xslt 从 xml 中删除元素?

【求助】Dom4j 生成xml,节点增加属性时,属性值中有特殊字符,如何做到不转义

XSD详解二 - 限定

Ant:如何在使用“过滤”复制 xml 文件时对属性值进行 xml 转义