使用具有导入的 xsd 验证 XML 文档

Dav*_*vid 1 c# xml xsd xsd-validation

我已经在互联网上搜索了 24 小时,但找不到有效的解决方案。

我有一个包含导入行的架构文件:

<xsd:import namespace="http://www.w3.org/2000/09/xmldsig#" 
            schemaLocation=
              "http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/xmldsig-core-schema.xsd"/>
Run Code Online (Sandbox Code Playgroud)

这是我验证 Xml 的代码:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add(null, @"C:\TEMP\myschema.xsd");

XmlReader xmlReader = XmlReader.Create(new StringReader(document.InnerXml), settings);
while (xmlReader.Read()) { }
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到:The 'http://www.w3.org/2000/09/xmldsig#:Signature' element is not declared.

如果我将代码(根据搜索建议)更改为:

settings.ValidationType = ValidationType.DTD;
settings.DtdProcessing = DtdProcessing.Parse;
Run Code Online (Sandbox Code Playgroud)

然后我没有收到错误,但验证不起作用,因为我故意插入了一个无效值来测试验证是否正常工作。

我尝试添加直接导入的架构:

settings.Schemas.Add(null, @"C:\TEMP\xmldsig-core-schema.xsd");
Run Code Online (Sandbox Code Playgroud)

但收到错误:For security reasons DTD is prohibited in this XML document. To enable DTD processing...

我已经尝试了我能想到的以及搜索建议的 XmlReaderSettings 设置的所有组合。

我现在真的很困惑。

Dav*_*vid 5

好吧,设法弄清楚了。一直盯着我的脸。

当我尝试将xmldsig-core-schema.xsd架构添加到 XmlReaderSettings 时,我收到以下消息:

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

以下代码是所需要的:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;

settings.Schemas.Add(null, @"C:\TEMP\myschema.xsd");

// Create new XmlReaderSettings with DtdProcessing set to Parse.
XmlReaderSettings settings2 = new XmlReaderSettings();
settings2.DtdProcessing = DtdProcessing.Parse;

// Create an XmlReader passing it the location of the problematic xsd and the new XmlReaderSettings.
XmlReader reader = XmlReader.Create(@"C:\TEMP\xmldsig-core-schema.xsd", settings2);

// Add the reader to the first XmlReaderSettings
settings.Schemas.Add(null, reader);
Run Code Online (Sandbox Code Playgroud)

我认为可能有一种更雄辩和简洁的方式来编写该代码,但我已经花了很长时间在它上面,我很高兴它能工作。如果有人想编辑它,请随意。

  • 在花了 3-4 个小时试图找出“DTD 禁止错误”之后,这解决了我的问题。我还设置了 **settings.MaxCharactersFromEntities = 1024;** 因为[这个](/sf/ask/241584241/) 。感谢您发布此信息..!!! (2认同)
  • 现货 - 解决了我的问题!一个答案的瑰宝,特别是因为它是在 7 多年前发布的;-) (2认同)