只是为了澄清,我正在使用XSLT 1.0。很抱歉一开始没有说明。
我有一个XSLT样式表,我想用可以安全进入JSON字符串的安全替换双引号。我正在尝试做类似以下的事情:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/message">
<xsl:variable name="body"><xsl:value-of select="body"/></xsl:variable>
{
"message" :
{
"body": "<xsl:value-of select="normalize-space($body)"/>"
}
}
</xsl:template>
</xsl:stylesheet>
如果我传入了XML,如下所示,这将始终正常工作:
<message>
<body>This is a normal string that will not give you any issues</body>
</message>
但是,我正在处理一个包含完整HTML的主体,这不是问题,因为normalize-space()
会处理HTML,而不是双引号。这打破了我:
<message>
<body>And so he quoted: "I will break him". The end.</body>
</message>
我真的不在乎双引号是HTML转义还是以反斜杠为前缀。我只需要确保最终结果通过JSON解析器。
此输出传递JSON Lint并且是一个合适的解决方案(反斜杠引号):
{ "body" : "And so he quoted: \"I will break him\". The end." }
答案 0 :(得分:8)
使用递归模板,您可以执行替换。此示例将"
替换为\"
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/message">
<xsl:variable name="escaped-body">
<xsl:call-template name="replace-string">
<xsl:with-param name="text" select="body"/>
<xsl:with-param name="replace" select="'"'" />
<xsl:with-param name="with" select="'\"'"/>
</xsl:call-template>
</xsl:variable>
{
"message" :
{
"body": "<xsl:value-of select="normalize-space($escaped-body)"/>"
}
}
</xsl:template>
<xsl:template name="replace-string">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="with"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:value-of select="$with"/>
<xsl:call-template name="replace-string">
<xsl:with-param name="text"
select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="with" select="$with"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
并产生输出:
{
"message" :
{
"body": "And so he quoted: \"I will break him\". The end."
}
}
答案 1 :(得分:2)
什么版本的XSLT?请记住,许多字符需要在JSON中进行特殊转义。虽然这在XSLT技术上是可行的,但它不会很漂亮。
如果您真的只关心反斜杠,并且您正在使用XSLT 1.0,那么各种string replace templates中的任何一个都应该为您完成。