[英]Xslt: escape XML nodes when producing HTML
我正在使用 Microsoft 的System.Xml.Xsl
創建HTML
。 將包含轉義序列(例如<script>
)的 XML 轉換為HTML
時,如果節點作為屬性發出,則它們不會被轉義。
我想生成 HTML,其中屬性和節點都被轉義了。
Xml 樣本:
<Contact>
<Name>hello <script>alert('!')</script></Name>
</Contact>
Xslt 樣本:
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:output method=""html"" indent=""yes"" doctype-system=""html"" />
<xsl:template match=""/"">
<span data-title=""{{ 'title': '{/Contact/Name}' }}"">
Name: <xsl:value-of select=""/Contact/Name""/>
Input: <input type=""text"" value=""{/Contact/Name}""/>
</span>
</xsl:template>
</xsl:stylesheet>
示例代碼:
using System;
using System.Xml;
using System.Xml.Xsl;
using System.IO;
public class Program
{
public static void Main()
{
var transform = new XslCompiledTransform();
var xml = @"<Contact><Name>hello <script>alert('!')</script></Name></Contact>";
var xslt = @"<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:output method=""html"" indent=""yes"" doctype-system=""html"" />
<xsl:template match=""/"">
<span data-title=""{{ 'title': '{/Contact/Name}' }}"">
Name: <xsl:value-of select=""/Contact/Name""/>
Input: <input type=""text"" value=""{/Contact/Name}""/>
</span>
</xsl:template></xsl:stylesheet>
";
transform.Load(XmlReader.Create(new StringReader(xslt)));
var settings = transform.OutputSettings.Clone();
using (var output = new MemoryStream())
using (var writer = XmlWriter.Create(output, settings))
{
var args = new System.Xml.Xsl.XsltArgumentList();
transform.Transform(XmlReader.Create(new StringReader(xml)), args, writer);
writer.Flush();
output.Position = 0;
Console.Write(new StreamReader(output).ReadToEnd());
}
}
}
實際結果(帶小提琴):
<!DOCTYPE html SYSTEM "html"><span data-title="{ 'title': 'hello <script>alert('!')</script>' }">
Name: hello <script>alert('!')</script>
Input: <input type="text" value="hello <script>alert('!')</script>"></span>
預期/期望的結果(帶有小提琴):
<!DOCTYPE span SYSTEM "html">
<span data-title="{ 'title': 'hello <script>alert('!')</script>' }">
Name: hello <script>alert('!')</script>
Input: <input type="text" value="hello <script>alert('!')</script>" /></span>
使用XSLT 3與XSL xsl:output method="xhtml"
,使用.NET框架使用Saxon .NET HE使用Saxonica或Saxonica或884205152630308 6/Cornecon(corter), HE 11.4 Java,如下所示,可能會給出更接近您需求的結果:
using net.sf.saxon.s9api;
using net.liberty_development.SaxonHE11s9apiExtensions;
using System.Reflection;
// force loading of updated xmlresolver (workaround until Saxon HE 11.5)
ikvm.runtime.Startup.addBootClassPathAssembly(Assembly.Load("org.xmlresolver.xmlresolver"));
ikvm.runtime.Startup.addBootClassPathAssembly(Assembly.Load("org.xmlresolver.xmlresolver_data"));
var processor = new Processor(false);
var xml = @"<Contact><Name>hello <script>alert('!')</script></Name></Contact>";
var xslt = @"<xsl:stylesheet version=""3.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:output method=""xhtml"" indent=""yes"" html-version=""5.0"" doctype-system=""about:legacy-compat"" omit-xml-declaration=""yes""/>
<xsl:template match=""/"">
<span data-title=""{{ 'title': '{/Contact/Name}' }}"">
Name: <xsl:value-of select=""/Contact/Name""/>
Input: <input type=""text"" value=""{/Contact/Name}""/>
</span>
</xsl:template></xsl:stylesheet>
";
var xslt30Transformer = processor.newXsltCompiler().compile(xslt.AsSource()).load30();
var inputDoc = processor.newDocumentBuilder().build(xml.AsSource());
using var resultWriter = new StringWriter();
xslt30Transformer.applyTemplates(inputDoc, processor.NewSerializer(resultWriter));
var result = resultWriter.ToString();
Console.WriteLine(result);
Output 例如
<!DOCTYPE span
SYSTEM "about:legacy-compat">
<span data-title="{ 'title': 'hello <script>alert('!')</script>' }">
Name: hello <script>alert('!')</script>
Input: <input type="text" value="hello <script>alert('!')</script>"/></span>
顯示使用 IKVM 和 Maven 來包含 Saxon HE 11.4 Java 的示例項目位於https://github.com/martin-honnen/SaxonHE1.NET7XHTMLOutputMethodExample1 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.