How do I fix “Could not find schema…” error while validating XML against XSD?
我使用的是相当复杂的第三方XSD格式——XSD指的是另一个XSD中的类型,它指的是另一个XSD中的类型。我需要能够根据这种格式验证XML。我已经能够使用XMLSpy验证这一点,但现在我们需要一种更自动化的方法。
我正在使用稍微复杂一点的代码版本加载XSD,但它们是等效的(只要我没有输入任何错别字):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | string xmlFile = @"C:\tmp\testxml\Valid.xml"; string xsdFile = @"C:\tmp\testxml\DRO.xsd"; var schema = new XmlSchemaCollection(); var reader = new FileStream(xmlFile, FileMode.Open); var validating = new XmlValidatingReader(reader, XmlNodeType.Element, null); // Removed 3 other XSDs to simplify a bit, but are included in the real code schema.Add("http://www.test.com/PTS/Formdom", @"C:\tmp\textxml\Formdom.xsd"); schema.Add("http://www.test.com/PTS/DRO", @"C:\tmp\textxml\DRO.xsd"); validating.ValidationType = ValidationType.Schema; validating.ValidationEventHandler += validating_ValidationEventHandler; while (validating.Read()) {} // More code removed |
XML文件看起来像这样-我已经将其裁剪到第一个错误发生的部分:
1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="UTF-8" ?> <dro:DRO xmlns:dro="http://www.test.com/PTS/DRO" xmlns:for="http://www.test.com/PTS/Formdom" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.test.com/PTS/DRO"> <dro:HeaderSection> <dro:VersionNumber>1.2</dor:VersionNumber> </dro:HeaderSection> </dro:DRO> |
号
dro.xsd看起来是这样的(同样,被严重削减了):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns="http://www.test.com/PTS/DRO" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:FF="http://www.test.com/PTS/FormFields" xmlns:CD="http://www.test.com/PTS/Formdom" xmlns:CF="http://www.test.com/PTS/CommonFields" targetNamespace="http://www.test.com/PTS/DRO" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:import namespace="http://www.test.com/PTS/FormFields" schemaLocation="FormFields.xsd"/> <xs:import namespace="http://www.test.com/PTS/Formdom" schemaLocation="FormDom.xsd"/> <xs:import namespace="http://www.test.com/PTS/CommonFields" schemaLocation="CommonFields.xsd"/> <xs:element name="DRO"> <xs:complexType> <xs:sequence> <xs:element name="HeaderSection" type="HeaderSection"/> </xs:sequence> </xs:complexType> |
我假设错误发生在xmlns和targetnamespace的配置方式上,并且我已经确保它们完全匹配(即使情况相同)。我还确保在C中添加模式时,目标名称空间匹配。在上面显示的代码中,我手动设置了名称,但在真正的代码中,我从xsd中提取targetnamespace并使用它。
当我运行代码时,我可以成功地添加所有XSD,但一旦它开始读取XML文件,它就会失败,并出现以下错误:
找不到元素的架构信息'http://www.test.com/pts/dro:dro'找不到元素的架构信息'http://www.test.com/pts/dro:headersection'
(加上大量其他类似错误)
我只是不明白我需要做什么才能使这项工作发挥作用。有什么想法吗?
编辑:我已经重新浏览了这段代码,并且意识到我实际上并没有对我的模式做任何事情。我正在将它们添加到XMLSchemaCollection中,但没有将其附加到任何内容。我修改了代码以使用xmlreadersettings()类,然后将架构添加到其架构集合中:
1 2 3 4 5 | var settings = new XmlReaderSettings(); // Code removed settings.Schema.Add("http://www.test.com/PTS/Formdom", @"C:\tmp\textxml\Formdom.xsd"); // Code removed var validating = XmlReader.Create(reader, settings); |
。
这看起来真的很管用(是的!)。我对XML文档做了一些小的更改,以使其失败,看起来它似乎正在捕获错误。
尝试为
1 2 3 4 5 6 | XmlReaderSettings settings = new XmlReaderSettings(); settings.ValidationType = ValidationType.Schema; settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; validating.Settings = settings; |
在这种情况下不需要
更多信息
- XmlSchemaValidationFlags
- XmlReaders设置