转换 XML 文件时出现“禁止 DTD”异常

Posted

技术标签:

【中文标题】转换 XML 文件时出现“禁止 DTD”异常【英文标题】:"DTD is prohibited" exception when transforming XML file 【发布时间】:2020-07-06 03:48:33 【问题描述】:

我创建了一个自定义的htmlHelper,它应该呈现已解析的 XML。该方法采用 XML 和 XSL 文件的路径,并应返回 HTML。

当我访问页面时,我得到了错误

XmlException:出于安全原因,此 XML 文档中禁止使用 DTD。要启用 DTD 处理,请将 XmlReaderSettings 上的 DtdProcessing 属性设置为 Parse 并将设置传递给 XmlReader.Create 方法。

正如您在下面的代码中看到的那样,我在XmlReaderSettings 中将DtdProcessing 设置为Parse(如异常所示),我认为这可以解决问题。仔细检查,异常发生在以下行:

transformObj.Load(xsltPath);

但我看不出如何将XmlReaderSettings 传递给该方法以设置DtdProcessing 属性。接受设置对象的 XslCompiledTransform.Load 的唯一重载需要 XsltSettings 对象,它没有 DtdProcessing 属性。

完整方法如下:

public static IHtmlContent RenderXml(this IHtmlHelper htmlHelper, string xml, string xsltPath)

    XsltArgumentList args = new XsltArgumentList();
    // Create XslCompiledTransform object to load and compile XSLT file.  
    XslCompiledTransform transformObj = new XslCompiledTransform();
    transformObj.Load(xsltPath);

    // Create XMLReaderSetting object to assign DtdProcessing, Validation type  
    XmlReaderSettings xmlSettings = new XmlReaderSettings();
    xmlSettings.DtdProcessing = DtdProcessing.Parse;
    xmlSettings.MaxCharactersFromEntities = 1024; // Prevent DoS attacks
    xmlSettings.ValidationType = ValidationType.DTD;

    // Create XMLReader object to Transform xml value with XSLT setting
    XmlReader reader = XmlReader.Create(new StringReader(xml), xmlSettings);

    using (reader)
    
        StringWriter writer = new StringWriter();
        transformObj.Transform(reader, args, writer);

        // Generate HTML string from StringWriter  
        HtmlString htmlString = new HtmlString(writer.ToString());
        return htmlString;
    

在我看来,我正在使用:

@Html.RenderXml(ViewBag.XML as string, ViewBag.XSL as string);

我已经查看了this question 答案中的建议,但据我所知,我已经采取了建议的步骤。 this MSDN question 接受的答案似乎暗示了一个答案,但我无法弄清楚如何使用它。

【问题讨论】:

尝试忽略而不是解析。 【参考方案1】:

如果 XSLT 使用或引用 DTD,则将带有必要 XmlReaderSettings 的 XmlReader 传递给 Load 方法,即使用重载 https://docs.microsoft.com/en-us/dotnet/api/system.xml.xsl.xslcompiledtransform.load?view=netframework-4.8#System_Xml_Xsl_XslCompiledTransform_Load_System_Xml_XmlReader_ with

using (XmlReader xsltReader = XmlReader.Create(xsltPath, new XmlReaderSettings()  DtdProcessing = DtdProcessing.Parse ))

  transformObj.Load(xsltReader);

【讨论】:

谢谢马丁,这就是我所缺少的 - 有一个接受 XmlReader 参数的重载。从那个 MSDN 答案开始已有 14 年了,您仍在帮助人们进行 XSL 转换!

以上是关于转换 XML 文件时出现“禁止 DTD”异常的主要内容,如果未能解决你的问题,请参考以下文章

使用地图转换消息时出现 Biztalk 2020 异常

读取 XML 元素时出现异常

“解析 XML 文件时出现异常:文件过早结束。”尝试将 svg 导入 Android Studio

从 ServletContext 资源解析 XML 文档时出现意外异常

反序列化包含简单引用实体的xml文件时出现异常

JSON转换时出现异常