我正在使用相当复杂的第三方XSD格式 - XSD指的是另一个XSD中的类型,它引用另一个XSD中的类型。我需要能够根据这种格式验证XML。我已经能够使用XML Spy进行验证,但现在我们需要一种更自动化的方法。
我使用稍微复杂的此代码版本加载XSD,但它们是等效的(只要我没有输入任何拼写错误):
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文件看起来像这样 - 我已经将它修剪为仅发生第一个错误的部分:
<?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看起来像这样(再次严重削减):
<?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()类,然后将模式添加到它的Schema集合中: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文档进行了一些小改动,使其失败,看起来它正在捕捉错误。
答案 0 :(得分:2)
尝试为XmlValidatingReader.Settings
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
validating.Settings = settings;
在这种情况下不需要 schema.Add()
,因为XmlSchemaValidationFlags.ProcessInlineSchema
将处理验证期间遇到的内联架构。
更多信息