我一直在网上搜索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设置的每个组合,并且已经通过搜索建议了。
我现在真的很难受。
答案 0 :(得分:1)
您写道:
当我运行它时,我得到:
http://www.w3.org/2000/09/xmldsig#:Signature
元素未被声明。
看起来它无法通过该URL加载导入的架构: http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/xmldsig-core-schema.xsd
我已经检查过该URL,并且该架构确实存在,以及该元素 {(1}}在其中声明(全局)。
但是加载该模式需要相当长的时间,显然是因为W3C阻止(并且实际上阻碍)来自众多软件的XML资源的巨大流量 全球各地。
关于这个:
但接收错误:出于安全原因,此XML文档中禁止使用DTD。 启用DTD处理...
我不确定您使用的是哪种编程系统(Java,.NET等),但它归结为其设置,可以通过您的代码或某些配置文件或环境变量传递给它。 / p>
该架构确实包含对必须加载的某些DTD(XMLSchema.dtd)的引用:
{http://www.w3.org/2000/09/xmldsig#}Signature
我建议您也从该网址加载该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 ''>
]>
并将其放在与架构相同的目录中。
然后,编辑模式文件并将DTD位置更改为相同(作为模式):
http://www.w3.org/2001/XMLSchema.dtd
...还需要<!DOCTYPE schema PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "XMLSchema.dtd" [
....
本地,因为它是从http://www.w3.org/2001/datatypes.dtd
引用的。
答案 1 :(得分:1)
跳过此验证的一种简单方法是在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 ''>
]>-->
答案 2 :(得分:0)
好的,设法搞清楚了。一直盯着我的脸。
当我尝试将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);
我认为编写该代码可能有更为雄辩和简洁的方法,但我花了很长时间才开始使用它,我很高兴它的工作原理。如果有人想编辑它,请随意。