2013-02-26 6 views
8

Załóżmy, że mam schemat, z którym chcę, aby dokument wejściowy był zgodny. Załaduję plik zgodnie ze schematem:Jak wymusić zgodność z danym schematem w .NET?

// Load the ABC XSD 
var schemata = new XmlSchemaSet(); 
string abcSchema = FooResources.AbcTemplate; 
using (var reader = new StringReader(abcSchema)) 
using (var schemaReader = XmlReader.Create(reader)) 
{ 
    schemata.Add(string.Empty, schemaReader); 
} 

// Load the ABC file itself 
var settings = new XmlReaderSettings 
{ 
    CheckCharacters = true, 
    CloseInput = false, 
    ConformanceLevel = ConformanceLevel.Document, 
    IgnoreComments = true, 
    Schemas = schemata, 
    ValidationType = ValidationType.Schema, 
    ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings 
}; 

XDocument inputDoc; 
try 
{ 
    using (var docReader = XmlReader.Create(configurationFile, settings)) 
    { 
     inputDoc = XDocument.Load(docReader); 
    } 
} 
catch (XmlSchemaException xsdViolation) 
{ 
    throw new InvalidDataException(".abc file format constraint violated.", xsdViolation); 
} 

Działa to dobrze w wykrywaniu drobnych błędów w pliku. Jednakże, ponieważ schemat jest zablokowana do nazw, dokument jak poniżej jest nieprawidłowy, ale zakrada przez:

<badDoc xmlns="http://Foo/Bar/Bax"> 
    This is not a valid document; but Schema doesn't catch it 
    because of that xmlns in the badDoc element. 
</badDoc> 

Chciałbym powiedzieć, że tylko nazw dla którego mam schematy powinny przechodzić walidację schematu.

Odpowiedz

2

tak głupi, jak się wydaje, co chcesz patrzeć na to faktycznie na obiekcie XmlReaderSettings:

settings.ValidationEventHandler += 
    (node, e) => Console.WriteLine("Bad node: {0}", node); 
+0

@codekaizen - hah, wystarczy, to jest "lepszy" przykład, chociaż podobało mi się domyślne zdziwienie mojego oryginału :) – JerKimball

+0

Uzgodnione, ale może istnieć jakiś powód (np. Nie wyrzucenie całego stosu i stanu parsowania) dla to, choć nie jest to zaskakujące, mam nadzieję, że epitet "głupi" przejmie całą odpowiedzialność za podkreślenie tego twistu. – codekaizen

+0

@codekaizen To niezmiernie dyplomatyczna z was; Szacunek osiągnięty. :) – JerKimball

1

roztworze skończyło się osiedleniem się na to, aby po prostu sprawdzić, czy węzeł główny jest w przestrzeni nazw Oczekuję. Jeśli tak nie jest, to traktuję to tak samo jak leczenie prawdziwej walidacji schematu:

// Parse the bits we need out of that file 
var rootNode = inputDoc.Root; 
if (!rootNode.Name.NamespaceName.Equals(string.Empty, StringComparison.Ordinal)) 
{ 
    throw new InvalidDataException(".abc file format namespace did not match."); 
} 
Powiązane problemy