繁体   English   中英

使用已导入的xsd验证XML文档

[英]Validate XML Document with xsd that has imports

我已经在互联网上拖拉了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... For security reasons DTD is prohibited in this XML document. To enable DTD processing...

我已经尝试过我能想到的XmlReaderSettings设置的每种组合,这些都已被搜索建议。

我现在真的很困惑。

你写了:

当我运行它时,我得到:未声明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资源的巨大流量。

关于此:

但是收到错误:出于安全原因,此XML文档中禁止使用DTD。 要启用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 : http://www.w3.org/2001/XMLSchema.dtd并将其放置在与架构相同的目录中。 然后,编辑架构文件并将DTD位置更改为相同(与架构相同):

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

...以及从XMLSchema.dtd引用的本地http://www.w3.org/2001/datatypes.dtd

跳过此验证的一种简单方法是在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 ''>
  ]>-->

确定设法解决。 一直盯着我。

当我尝试将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);

我认为可能有一种更雄辩,更简洁的方法来编写该代码,但是我花了很长时间才对它起作用感到高兴。 如果有人要进行编辑,请随意。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM