1

変換するxmlに次のアイテム名があります

<title>abc \" &gt; &lt; script &gt; alert(1) &lt; /script &gt;</title>

XSL ファイルで次を使用して変換します。

<xsl:attribute name="itemTitle"><xsl:value-of select="title"/></xsl:attribute>

C# の XSLCompiledTransform の Transform 関数を使用しています。私のコードは次のとおりです。

XPathDocument xpTemplate = new XPathDocument("articlesLookupTemplate.xsl");
XslCompiledTransform xsl = new XslCompiledTransform();
XsltArgumentList xslArg = new XsltArgumentList();
xsl.Load(xpTemplate);

using (StringReader reader = new StringReader(xmlData))
{
    xsl.Transform(XmlReader.Create(reader), xslArg, output);
} 

output は HtmlTextWriter です。XSLT を介して変換した後、エスケープしたままにしたい、つまり、出力はそのままにしておく必要があります

itemTitle="abc&quot; &gt; &lt; script &gt; alert(1) &lt; /script &gt;"

しかし、私が得るものは:

itemTitle="abc&quot;><script>alert(1)</script>"

xsl ファイルで html 出力方法を使用していますが、disable-output-escaping はありません。テキスト出力方法を試すと、切り捨てられた出力が得られます。テキストがそのまま残るようにするにはどうすればよいですか。

--- 更新 --- www.xmlper.com で xsl と xml を試しました

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0">
<xsl:output method="html" />
<xsl:template match="/articles">
<table id="TemplateTable">
     <xsl:for-each select="articletemplate">
        <li class="Dialog-ListItem">
           <xsl:attribute name="itemTitle"><xsl:value-of select="title"/></xsl:attribute>
           <xsl:value-of select="title"/>
        </li>
      </xsl:for-each>  
</table>
</xsl:template>
</xsl:stylesheet>

XMLファイルは次のとおりです。

<articles >
  <articletemplate>  
  <title>abc " &gt; &lt; script &gt; alert(1) &lt; /script &gt;</title>
  </articletemplate>
</articles>

xmlattribute のものについては、

itemTitle="abc &quot; > < script > alert(1) < /script >"

そしてそれのないもののために私は得る

abc " &gt; &lt; script &gt; alert(1) &lt; /script &gt;

xmlattribute 内のものもエンコードしたかったのです。

4

3 に答える 3

2

まず、あなたの出力についてコメントさせてください。あなたは以下を使用しています:

<table id="TemplateTable">
     <xsl:for-each select="articletemplate">
        <li class="Dialog-ListItem">
           <xsl:attribute name="itemTitle"><xsl:value-of select="title"/></xsl:attribute>
           <xsl:value-of select="title"/>
        </li>
      </xsl:for-each>  
</table>

liこれはの子として生成されますtable- これは適切な HTML ではありません (w3c.org で試したときは確かに検証されませんでした)。または<li>の子である必要があります<ul><ol>

それはさておき、これは実際には非常に興味深い質問です。その理由は、仕様との不一致によるものだと思います。

html 出力メソッドは、属性値で発生する < 文字をエスケープしないでください。

(出典: http://www.xm.co.nz/ShoXS/xsloutput.htm )

これが私が起こっていると思うことです:

パーサーの xsl:value-of は、abc \&quot; &amp;gt; &amp;lt; script &amp;gt; alert(1) &amp;lt; /script &amp;gt;すぐに変換されるものを確認しabc \&quot; > < script > alert(1) < /script >ます。次に、上記のルールに従って、これを属性値に逐語的に配置する必要があります (これも私が観察したことです)。

これはほぼ間違いなく、html 出力宣言によるものです。出力を XML に変更すると、値はそのまま属性に配置されます。

したがって、次の 2 つのオプションがあります。

  1. (出力を に変更することにより) XML に直接変換xmlし、それをクライアントに書き出そうとします。XML である可能性がありますが、(XML 宣言を省略し、HTTP の正しいコンテンツ タイプを使用して) HTML として送信する場合は、期待どおりに記述されるはずです。

  2. テキストを CDATA として配置します: <![CDATA[abc " &gt; &lt; script &gt; alert(1) &lt; /script &gt;]]>- これは、.Net Xml パーサーがテキストを HTML として扱わないように強制するように見えます (そのため、出力方法が の場合、出力される前に翻訳されませんhtml)。結果は希望どおりになります。

がここでは影響を与えないことにも注意しdisable-output-escapingてください。これはほぼ確実に、出力方法がhtml

XmlDocument、XSLTransform、.Net 3.5 を使用してテスト済み

これが私が書いたXSLTです:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">
  <xsl:output method="html" />
  <xsl:template match="/">
    <html>
      <head></head>
      <body>
        <ul>
          <xsl:apply-templates select="/articles/articletemplate" />
        </ul>
      </body>
    </html>
  </xsl:template>


  <xsl:template match="articletemplate">
    <li class="Dialog-ListItem" itemTitle="{title}">
      <xsl:value-of select="title"/>
    </li>
  </xsl:template>  
</xsl:stylesheet>

私が使用したサンプル XML (CDATA と非 CDATA に注意してください):

<?xml version="1.0" encoding="utf-8" ?>
<articles>
  <articletemplate>
    <title><![CDATA[abc \" &gt; &lt; script &gt; alert(1) &lt; /script &gt;]]></title>
  </articletemplate>
  <articletemplate>
    <title>abc " &gt; &lt; script &gt; alert(1) &lt; /script &gt;</title>
  </articletemplate>
  <articletemplate>
    <title>test</title>
  </articletemplate>
</articles>

そして出力:

<html>
  <head>
    <META http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <ul>
      <li class="Dialog-ListItem" itemTitle="abc \&quot; &amp;gt; &amp;lt; script &amp;gt; alert(1) &amp;lt; /script &amp;gt;">abc \" &amp;gt; &amp;lt; script &amp;gt; alert(1) &amp;lt; /script &amp;gt;</li>
      <li class="Dialog-ListItem" itemTitle="abc &quot; > < script > alert(1) < /script >">abc " &gt; &lt; script &gt; alert(1) &lt; /script &gt;</li>
      <li class="Dialog-ListItem" itemTitle="test">test</li>
    </ul>
  </body>
</html>
于 2012-08-24T14:01:02.963 に答える
1

XSLT プロセッサは元の形式が何であるかを認識していないため、属性値の元の形式を保持する方法はありません。属性値のエンティティー参照は、XML パーサーによって展開され、「展開された」形式 (つまり、変換されたものなど) で XSLT プロセッサーに渡され&lt;ます<。xsl:value-of の最終的な結果は、属性値内の '"' を自由に出力できる HTML シリアライゼーション メソッドに依存し&quot;ます&#34;。 HTML のエスケープされていない形式の '>' は正当かどうか - 私の最初の直感は、それは正当ではないということです。これはプロセッサのバグです。

于 2012-08-24T08:19:47.927 に答える
0

私はあなたの問題を再現できませんでした。

www.xmlper.comで、次の出力が得られました。

<t itemTitle="abc \&quot; &gt; &lt; script &gt; alert(1) &lt; /script &gt;" />

そしてSaxonで、私は出力を得ました:

<t itemTitle="abc \&#34; &gt; &lt; script &gt; alert(1) &lt; /script &gt;"/>

あなたが持っていると主張するものをどうやって手に入れることができるのか分かりません。XSLTプロセッサが非準拠であるか、一部のDOMパーサーが出力属性の字句レンダリングで報告するため、出力属性の値を混同しています。

于 2012-08-24T07:32:03.863 に答える