简体   繁体   English

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

[英]Validate XML Document with xsd that has imports

I've been trawling the internet for a good 24 hours and just can't find a resolution that works. 我已经在互联网上拖拉了24小时,但找不到有效的解决方案。

I have a schema file that contains an import line: 我有一个包含导入行的架构文件:

<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"/>

Here is my code to validate the Xml: 这是验证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()) { }

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

If I change my code (as suggested by searches) to: 如果我将代码(如搜索建议)更改为:

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

Then I receive no error but the validation doesn't work as there is I have deliberately inserted an invalid value to test that the validation is working. 然后,我没有收到任何错误,但是验证不起作用,因为我故意插入了一个无效值来测试验证是否有效。

I've tried adding the schema being imported directly: 我尝试添加直接导入的架构:

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

But receieve the error: 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... For security reasons DTD is prohibited in this XML document. To enable DTD processing...

I've tried every combination of XmlReaderSettings settings I can think of and that have been suggested by searches. 我已经尝试过我能想到的XmlReaderSettings设置的每种组合,这些都已被搜索建议。

I'm really just proper stumped now. 我现在真的很困惑。

You wrote: 你写了:

When I run it I get: The http://www.w3.org/2000/09/xmldsig#:Signature element is not declared. 当我运行它时,我得到:未声明http://www.w3.org/2000/09/xmldsig#:Signature元素。

Looks like it just cannot load that imported schema by that URL: http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/xmldsig-core-schema.xsd 看起来它只是无法通过该URL加载导入的架构: http : //www.w3.org/TR/2001/PR-xmldsig-core-20010820/xmldsig-core-schema.xsd

I've checked that URL and the schema does exist there, as well as the element {http://www.w3.org/2000/09/xmldsig#}Signature is declared in it (globally). 我检查了URL和架构是否确实存在,以及元素{http://www.w3.org/2000/09/xmldsig#}Signature声明了签名(全局)。

But it takes rather long time to load that schema, apparently because W3C discourages (and actually hinders) the huge traffic to their XML resources from numerous software around the globe. 但是加载该模式需要花费相当长的时间,这显然是因为W3C阻止(并实际上阻碍了)来自全球各地众多软件对其XML资源的巨大流量。

Concerning this: 关于此:

But receieve the error: For security reasons DTD is prohibited in this XML document. 但是收到错误:出于安全原因,此XML文档中禁止使用DTD。 To enable DTD processing... 要启用DTD处理...

I am not sure which programming system you use (Java, .NET etc), but it comes down to its settings, which may be passed to it either via your code or some config file(s) or environment variables. 我不确定您使用的是哪种编程系统(Java,.NET等),但是它取决于其设置,可以通过您的代码或某些配置文件或环境变量将其传递给它。

That schema does include a reference to some DTD (XMLSchema.dtd) that must be loaded: 该架构确实包含对必须加载的某些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 ''>
]>

I suggest you also to load that DTD from that URL: http://www.w3.org/2001/XMLSchema.dtd and place it in the same directory as the schema. 我建议您也从该URL加载该DTD: http://www.w3.org/2001/XMLSchema.dtd : http://www.w3.org/2001/XMLSchema.dtd并将其放置在与架构相同的目录中。 Then, edit the schema file and change the DTD location to be the same (as schema): 然后,编辑架构文件并将DTD位置更改为相同(与架构相同):

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

... and also http://www.w3.org/2001/datatypes.dtd will be required locally as it is referenced from XMLSchema.dtd . ...以及从XMLSchema.dtd引用的本地http://www.w3.org/2001/datatypes.dtd

An easy way to skip this validation was commenting the first lines (DTD part) on xmldsig-core-schema.xsd 跳过此验证的一种简单方法是在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 ''>
  ]>-->

Ok managed to figure it out. 确定设法解决。 Was staring me in the face the whole time. 一直盯着我。

When I tried to add the xmldsig-core-schema.xsd schema to the XmlReaderSettings I got the following message: 当我尝试将xmldsig-core-schema.xsd模式添加到XmlReaderSettings时,出现以下消息:

For security reasons DTD is prohibited in this XML document. 出于安全原因,此XML文档中禁止使用DTD。 To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings into XmlReader.Create method. 若要启用DTD处理,请将XmlReaderSettings上的DtdProcessing属性设置为Parse并将设置传递到XmlReader.Create方法。

The following code is what was needed: 需要以下代码:

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);

I think there is probably a more eloquent and succinct way to write that code but I've spent so long on it I'm just happy it works. 我认为可能有一种更雄辩,更简洁的方法来编写该代码,但是我花了很长时间才对它起作用感到高兴。 If anyone wants to edit it feel free. 如果有人要进行编辑,请随意。

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

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