1

明確にするために、私は XSLT 1.0 を使用しています。最初に指定しなかったことをお詫びします。

二重引用符を、JSON 文字列に入っても安全な何かに置き換えたい XSLT スタイルシートがあります。私は次のようなことをしようとしています:

<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." } 
4

2 に答える 2

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="'&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."
}
}
于 2013-09-12T02:12:23.067 に答える
2

XSLT のバージョンは? JSONでは、多くの文字が特別なエスケープを必要とすることに注意してください。これは XSLT で技術的には可能ですが、きれいではありません。

ただし、バックスラッシュだけが本当に気になる場合で、XSLT 1.0 を使用している場合は、さまざまな文字列置換テンプレートのいずれかを使用する必要があります。

于 2013-09-12T02:12:41.073 に答える