关于c#:如何在针对XSD验证XML时修复“无法找到模式…”错误?

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文档做了一些小的更改,以使其失败,看起来它似乎正在捕获错误。


尝试为XmlValidatingReader.Settings添加这些设置

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;

在这种情况下不需要schema.Add(),因为XmlSchemaValidationFlags.ProcessInlineSchema将处理验证期间遇到的内联模式。

更多信息

  • XmlSchemaValidationFlags
  • XmlReaders设置