【问题标题】:XSLT replace double quotes in variableXSLT 替换变量中的双引号
【发布时间】:2013-09-12 01:57:25
【问题描述】:

澄清一下,我使用的是 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." } 

【问题讨论】:

    标签: xml json xslt xpath


    【解决方案1】:

    使用递归模板,您可以执行替换。此示例将" 替换为\"

    <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="'&quot;'" />
                    <xsl:with-param name="with" select="'\&quot;'"/>
                </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."
    }
    }
    

    【讨论】:

    • 这是完美的。谢谢。
    • 正是我想要的。谢谢!
    【解决方案2】:

    什么版本的 XSLT?请记住,JSON 中的许多字符需要特殊转义。虽然这在 XSLT 中在技术上是可行的,但它不会很漂亮。

    如果您真的只关心反斜杠,并且您使用的是 XSLT 1.0,那么各种 string replace templates 中的任何一个都应该为您服务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-11
      • 2016-02-09
      • 2015-08-01
      • 2018-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多