2013-05-26 16 views
5

Jako programista z dużym doświadczeniem i doświadczeniem XML, nigdy wcześniej nie wchodziłam w interakcje z schematami. Po raz pierwszy tak naprawdę dzieje się dla mnie.Sprawdzanie poprawności dokumentów XML z XSD poprawnie

Przebiegłem przez "funkcję", którą uważam za bardziej błędny, który jest dobrze udokumentowany.

Podczas używania XDocument.Validate() wydaje się, że są przypadki, w których dokument będzie ważny, jeśli nie pasuje do określonego schematu. Uważam, że jest to najprawdopodobniej wada mojego rozumienia związku między XSD, przestrzeniami nazw XML i oczekiwanymi procesami walidacji.

Dlatego przesyłam wam moją próbkę XML, próbkę XSD i mój kod weryfikacyjny.

XML - jest to POKUTNIE zły dokument.

<?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 użyty do sprawdzenia poprawności. (Ponownie, jest to celowo NIEPRAWIDŁOWY dokument dla powyższego 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> 

I na koniec kod weryfikacyjny.

Zastanawiam się, czy ktoś może wyjaśnić, co robię źle. Czuję, że tworzę niepoprawne założenia dotyczące tego, jak to powinno działać. Wydaje mi się, że użycie jednego xsd przeciwko całkowicie niepowiązanemu dokumentowi XML byłoby nieprawidłowe.

+0

Walidacja Xsd zwykle generuje ostrzeżenie, gdy nie można znaleźć pożądanego schematu. Do wyboru są tylko błędy. –

+1

Tak nie jest w tym przypadku, zobacz: http://msdn.microsoft.com/en-us/library/bb354954(v=vs.90).aspx, aby uzyskać szczegółowe informacje na temat XDocument.Validate. To szczególne przeciążenie sprawdzania poprawności spowoduje wychwycenie błędów i ostrzeżeń. –

Odpowiedz

3

Nie ma węzłów w twoim XML, które mogą być sprawdzone przez schemat (przestrzenie nazw są różne). W rezultacie nie zgłasza żadnych błędów. O ile wiem, zachowanie dla węzłów, które nie są dopasowane do żadnego schematu, pozwala na wszystko.

też może ustawić validation options in XmlReaderSettings aby umożliwić ostrzeżenia:

ReportValidationWarnings - Wskazuje, że wydarzenia powinny być zgłaszane, jeśli wystąpi ostrzeżenie walidacji. Ostrzeżenie jest zwykle generowane, gdy nie ma DTD ani schematu XML do sprawdzenia poprawności konkretnego elementu lub atrybutu. ValidationEventHandler służy do powiadamiania.

Wyjazd XmlSchemaSet.Add i HOW TO: Validate an XML Document by Using Multiple Schemas jeśli oczekujesz węzły z wielu nazw, aby być obecny w XML.

+0

W tym przypadku prawdziwym problemem jest brak schematów w schematach XmlSchemaSet, które pasują do schematu obszaru nazw określonego w katalogu głównym dokumentu, czy nie? czy nie powinno to być wykonalne? –

+0

@ DanielGreen to jest, ale nie pamiętam jak ... Dodałem link do zgłaszania ostrzeżeń, więc powinien dać ci znać o elementach, które nie mają schematu. –

+0

To wszystko dobrze i dobrze, ale obecny projekt zajmuje XDocument, a ja wolałbym tego nie zmieniać, ale ładowanie strumienia dwukrotnie wydaje się również błędne, zwłaszcza, że ​​w tym kontekście nie jest jasne, co załadować. –