我的xml中有以下项目名称要转换
<title>abc \" > < script > alert(1) < /script ></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" > < script > alert(1) < /script >"
但我得到的是:
itemTitle="abc"><script>alert(1)</script>"
我在我的xsl文件中使用html输出方法,并且没有禁用 - 输出 - 转义。如果我尝试文本输出方法,我得到截断输出。如何确保文本保持原样。
---更新--- 我在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 " > < script > alert(1) < /script ></title>
</articletemplate>
</articles>
对于xmlattribute中的那个我得到了
itemTitle="abc " > < script > alert(1) < /script >"
对于没有它的那个我得到了
abc " > < script > alert(1) < /script >
我希望xmlattribute中的那个也被编码。
答案 0 :(得分: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输出方法不应该转义&lt;字符发生在 属性值。
(资料来源:http://www.xm.co.nz/ShoXS/xsloutput.htm)
以下是我的想法:
解析器中的xsl:value-of会看到abc \" &gt; &lt; script &gt; alert(1) &lt; /script &gt;
,它会立即转换为abc \" > < script > alert(1) < /script >
。然后,根据上面的规则,这应该逐字地放入属性值(这也是我所观察到的)。
这几乎可以肯定是由于html输出声明。如果我将输出更改为XML,则将值逐字放入属性中。
所以你有两个选择:
直接转换为XML(通过将输出更改为xml
)并尝试将其写入客户端。它可能是XML,但如果您将其作为HTML发送(通过省略XML声明并使用HTTP的正确内容类型),则应按预期编写。
将文本放置为CDATA:<![CDATA[abc " > < script > alert(1) < /script >]]>
- 这似乎强制.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 \" > < script > alert(1) < /script >]]></title>
</articletemplate>
<articletemplate>
<title>abc " > < script > alert(1) < /script ></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 \" &gt; &lt; script &gt; alert(1) &lt; /script &gt;">abc \" &gt; &lt; script &gt; alert(1) &lt; /script &gt;</li>
<li class="Dialog-ListItem" itemTitle="abc " > < script > alert(1) < /script >">abc " > < script > alert(1) < /script ></li>
<li class="Dialog-ListItem" itemTitle="test">test</li>
</ul>
</body>
</html>
答案 1 :(得分:1)
没有办法保留属性值的原始形式,因为XSLT处理器不知道原始形式是什么;属性值中的实体引用由XML解析器扩展,并以“扩展”形式传递给XSLT处理器(即,<
被转换为<
,依此类推)。 xsl:value-of的最终结果取决于HTML序列化方法,该方法可以在属性值中以"
或"
或其他各种等效方式自由输出“”。没有仔细调查是否输出'&lt;'和'&gt;'在HTML中未转义的形式是合法与否 - 我的第一个问题是它不合法,这是你的处理器中的一个错误。
答案 2 :(得分:0)
我无法重现你的问题。
在www.xmlper.com上,我得到了输出:
<t itemTitle="abc \" > < script > alert(1) < /script >" />
有了Saxon,我得到了输出:
<t itemTitle="abc \" > < script > alert(1) < /script >"/>
我不知道怎么可能得到你声称你得到的东西。您的XSLT处理器是不符合要求的,或者您在输出属性的值与某些DOM解析器报告它时混淆了输出属性的词汇呈现。