正确地用XSD验证XML文档
本文关键字:XML 文档 验证 XSD 正确地 | 更新日期: 2023-09-27 18:15:27
作为一个具有大量XML消费和生产经验的开发人员,我以前从未真正与模式进行过交互。这是第一次真正发生在我身上。
我遇到了一个"特性",我认为它更像是一个bug,它被很好地记录了下来。
当使用XDocument.Validate()时,似乎在某些情况下,如果文档与指定的模式不匹配,它将是有效的。我觉得这很可能是我对xsd、XML名称空间和预期验证过程之间关系的理解中的一个缺陷。
因此,我向您提交我的XML示例、XSD示例和验证代码。
XML -这是故意错误的文档。
<?xml version="1.0" encoding="utf-8" ?>
<SuppliesDefinitions
xmlns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Supplies.xsd">
<Supply type="Common">
<Information/>
<Ritual/>
<Weapon/>
<Tool count="1"/>
<Tool count="2"/>
<Tool count="3"/>
</Supply>
<Supply type="Uncommon">
<Information/>
<Weapon/>
<Tool count="1"/>
<Tool count="2"/>
<Tool count="3"/>
<Tool count="4"/>
</Supply>
<Supply type="Rare">
<Information/>
<Rune/>
<Weapon/>
<Tool count="2"/>
<Tool count="3"/>
<Tool count="4"/>
</Supply>
</SuppliesDefinitions>
用于验证的XSD。(同样,这是有意为上述XML编写的错误文档)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Encounters"
targetNamespace="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd"
elementFormDefault="qualified"
xmlns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd"
xmlns:mstns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="ToolType">
<xs:attribute name="count" use="required" type="xs:int"/>
</xs:complexType>
<xs:complexType name="TaskType">
<xs:choice maxOccurs="unbounded" minOccurs="1">
<xs:element name="Weapon"/>
<xs:element name="Information"/>
<xs:element name="Tool" type="ToolType"/>
<xs:element name="Ritual"/>
</xs:choice>
</xs:complexType>
<xs:complexType name="EncounterType">
<xs:sequence maxOccurs="unbounded" minOccurs="1">
<xs:element name="Task" type="TaskType"/>
</xs:sequence>
<xs:attribute name="name" use="required" type="xs:string"/>
</xs:complexType>
<xs:element name="EncounterDefinitions">
<xs:complexType>
<xs:sequence maxOccurs="unbounded" minOccurs="1">
<xs:element name="Encounter" type="EncounterType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
最后是验证码
private static void ValidateDocument(XDocument doc)
{
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(null, XmlReader.Create(new StreamReader(XmlSchemaProvider.GetSchemaStream("Encounters.xsd"))));
doc.Validate(schemas, (o, e) =>
{
//This is never hit!
Console.WriteLine("{0}", e.Message);
Assert.False(e.Severity == XmlSeverityType.Error);
});
}
我想知道是否有人可以解释我做错了什么。我觉得我做了一些错误的假设,这应该是工作的方式。在我看来,对一个完全不相关的XML文档使用一个xsd是无效的。
XML中没有可以由模式验证的节点(名称空间不同)。因此,它不会报告任何错误。据我所知,不匹配任何模式的节点的行为是允许任何东西。
您还可以在XmlReaderSettings中设置验证选项以允许警告:
ReportValidationWarnings -指示如果发生验证警告,应该报告事件。当没有DTD或XML Schema来验证特定元素或属性时,通常会发出警告。ValidationEventHandler用于通知。
查看XmlSchemaSet。如果您希望在XML中出现来自多个名称空间的节点,则添加和如何:使用多个模式验证XML文档。