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

本文关键字:xsd 验证 XML 文档 导入 | 更新日期: 2023-09-27 18:21:05

我在互联网上搜索了整整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"/>

以下是我验证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()) { }

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

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

settings.ValidationType = ValidationType.DTD;
settings.DtdProcessing = DtdProcessing.Parse;

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

我已经尝试添加直接导入的模式:

settings.Schemas.Add(null, @"C:'TEMP'xmldsig-core-schema.xsd");

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

我已经尝试了我能想到的和搜索建议的XmlReaderSettings设置的每一种组合。

我现在真的被难住了。

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

Ok设法解决了这个问题。一直盯着我的脸。

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

出于安全原因,此XML文档中禁止使用DTD。启用DTD处理将XmlReaderSettings的DtdProcessing属性设置为分析设置并将其传递到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);

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

您写道:

当我运行它时,我得到:http://www.w3.org/2000/09/xmldsig#:Signature元素没有声明。

看起来它无法通过该URL加载导入的架构:http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/xmldsig-core-schema.xsd

我已经检查了URL和模式是否存在,以及元素{http://www.w3.org/2000/09/xmldsig#}Signature在其中声明(全局)。

但是加载该模式需要相当长的时间,这显然是因为W3C不鼓励(实际上也阻碍)大量软件对其XML资源的巨大流量世界各地。

关于此:

但是收到错误:出于安全原因,DTD在这个XML文档中是被禁止的。要启用DTD处理。。。

我不确定你使用的是哪种编程系统(Java、.NET等),但归根结底是它的设置,这些设置可能通过你的代码或一些配置文件或环境变量传递给它。

该模式确实包含对必须加载的某些DTD(XMLSchema.DTD)的引用:

<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" 
                        "http://www.w3.org/2001/XMLSchema.dtd" [
  <!ATTLIST schema xmlns:ds CDATA #FIXED 'http://www.w3.org/2000/09/xmldsig#'>
  <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
  <!ENTITY % p ''>
  <!ENTITY % s ''>
]>

我建议您也从该URL加载DTD:http://www.w3.org/2001/XMLSchema.dtd并将其放置在与模式相同的目录中。然后,编辑模式文件并将DTD位置更改为与模式相同:

<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "XMLSchema.dtd" [
....

并且由于从CCD_ 8引用CCD_。

跳过此验证的一个简单方法是注释xmldsig-core-schema.xsd 上的第一行(DTD部分)

<!--<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd" [
   <!ATTLIST schema 
     xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#">
   <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
   <!ENTITY % p ''>
   <!ENTITY % s ''>
  ]>-->