作爲一名具有大量XML消費和生產經驗的開發人員,我從未真正與模式進行過交互。這是我第一次實際發生。使用XSD正確驗證XML文檔
我已經運行了一個「功能」,我認爲更多的是有據可查的錯誤。
使用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);
});
}
我想知道如果有人能解釋我做錯了什麼。我覺得我對這種SHOULD的工作方式做了一些不正確的假設。在我看來,對一個完全不相關的XML文檔使用一個xsd將是無效的。
Xsd驗證通常僅在找不到所需架構時纔會生成警告。你很可能只會檢查錯誤。 –
這不是這種情況,請參閱:http://msdn.microsoft.com/en-us/library/bb354954(v=vs.90).aspx XDocument.Validate的詳細信息。驗證的這個特定的重載將會捕獲錯誤和警告。 –