Poznáváme C# a Microsoft.NET 45. díl – validace XML dokumentů

V dnešním díle, který bude opět pojednávat o práci s XML dokumenty se zaměříme na jednu důležitou úlohu ve světě XML, kterou je validace XML dokumentů podle XML schémat a její aplikací ve světě .NET.

XML schémata

Zatím jsme se zabývali pouze čtením nebo tvorbou XML dokumentů nebo jejich částí a to jak pomocí jednosměrných čtení či zápisů (XMLReader/XMLWriter) tak s využitím modelu DOM. Tyto akce jsou jistě v řadě případů dostačující avšak můžeme potřebovat definovat i pravidla určující jakou strukturu mají nově vznikající XML dokumenty mít. K tomu nám ve světě XML v zásadě slouží dva způsoby. Prvním je DTD (Dokument Type Definition), což je starší způsob, který při kýžené definici nepoužívá syntaxi jazyka XML. Druhým způsobem jsou takzvaná XML Schémata (XSD - XML Schema Definition), která představují modernější způsob definice pravidel pro XML dokumenty a tento způsob je na rozdíl od DTD realizován pomocí XML syntaxe. My se v našem dnešním díle budeme zabývat použitím XML schémat, přesněji validací dokumentů podle nich v .NET frameworku.

Zprvu si uvedeme jednoduché XML schéma a pro ty, kteří s touto věcí ještě nepřišli do styku uvedené schéma alespoň stručně popíšu.

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="Zamestnanci"
                  targetNamespace="
http://tempuri.org/Zamestnanci.xsd"
                  elementFormDefault="qualified"
                  xmlns="
http://tempuri.org/Zamestnanci.xsd"
                  xmlns:xs="
http://www.w3.org/2001/XMLSchema">
 <xs:element name="zamestnanci">
  <xs:complexType>
   <xs:sequence maxOccurs="unbounded">
    <xs:element name="zamestnanec">
     <xs:complexType>
      <xs:sequence>
       <xs:element name="jmeno" type="xs:string"></xs:element>
       <xs:element name="prijmeni" type="xs:string"></xs:element>
       <xs:element name="vek" type="xs:byte"></xs:element>   
      </xs:sequence>
     </xs:complexType>
    </xs:element>
   </xs:sequence>
  </xs:complexType>
 </xs:element>
</xs:schema>

Elementy používané pro definici XML schémat se nacházeji ve XML jmenném prostoru http://www.w3.org/2001/XMLSchema, a v dokumentu je pro ně použit prefix xs. Pomocí atributu targetNamespace elementu schema určíme do jakého XML jmenného prostoru budou námi definované typy (elementy) patřit. Schéma předepisuje strukturu dokumentu, ve které se bude nacházet element s názvem zamestnanci, což je v jazyce XML schémat komplexní typ a to znamená, že může obsahovat atributy a vnořené elementy narozdíl od takzvaných jednoduchých typů, které mohou obsahovat pouze text. A v elementu zamestanci se může nacházet libovolný počet elementů zamestnanec, což je definováno atributem maxOccurs, který má hodnotu unbounded. A konečně v elementu zamestnanec by se měli nacházet elementy jmeno, prijmeni a vek.

Nyní ještě potřebujeme pokusný dokument, který je podle tohoto schématu vytvořen, aby jsme jej později v C# validovat (= zkontrolovat jestli splňuje strukturu danou schématem).

<?xml version="1.0" encoding="utf-8" ?>
<zamestnanci xmlns="
http://tempuri.org/Zamestnanci.xsd"
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://tempuri.org/Zamestnanci.xsd Zamestnanci.xsd">
 <zamestnanec>
  <jmeno>Petr</jmeno>
  <prijmeni>Pus</prijmeni>
  <vek>21</vek>
 </zamestnanec>
 <zamestnanec>
  <jmeno>Jirka</jmeno>
  <prijmeni>Mecner</prijmeni>
  <vek>23</vek>
 </zamestnanec>
</zamestnanci>

To, že je tento dokument podle našeho schématu, je uvedeno určením výchozího jmenného prostoru (bez prefixu) pomocí atributu xmlns a lokace asociovaného schématu se určuje pomocí atributu schemaLocation z XML jmenného prostoru http://www.w3.org/2001/XMLSchema-instance.

Validace podle XSD v .NET frameworku

Po letmém vysvětlení použití XML schémat, bych rád přešel k tomu nejdůležitějšímu v dnešním článku, čímž je pro mě vysvětlení způsobu validace XML dokumentu v .NET. Věřím, že si vzpomínáte na jeden z nedávných dílů tohoto seriálu, kde jsme se zabývali parsingem XML pomocí implementací třídy XMLReader. A právě jednou z těchto implementací této třídy je třída XMLValidatingReader, která nám poslouží pro naše dnešní záměry. Tak se konečně podívejme jak pomocí této třídy na to.

public static void ValidaceDokumentu()
{
 XmlTextReader lReader = new XmlTextReader("C:/vyvojari.xml");
 XmlValidatingReader lValReader = new XmlValidatingReader(lReader);
 //urcime ze se provadi validace podle XML schematu
 lValReader.ValidationType = ValidationType.Schema;
 //priradime validacni handler
 lValReader.ValidationEventHandler += new ValidationEventHandler(lValReader_ValidationEventHandler);
 //provedeme vlastni validacni cteni
 while (lValReader.Read()){}
 Console.WriteLine("Validace XML dokumentu dokoncena");
}

private static void lValReader_ValidationEventHandler(object sender, ValidationEventArgs e)
{
 //vypsani zavaznosti
 Console.WriteLine(e.Severity);
 //vypsani duvodu chyby
 Console.WriteLine(e.Message);
}

Po té co inicializujeme novou instanci třídy XMLValidationReader, specifikujeme pomocí instanční vlastnosti ValidationType jakým způsobem bude probíhat validace XML dokumentu. V našem případě je to samozřejmě podle XML schématu. Další důležitou věcí, kterou bysme měli při validování dokumentu učinit je definovat metodu, která bude instancí delegáta ValidationEventHandler. Tento handler slouží k získavání informací o validačních chybách. Pomocí metody Read, jednoduše projedeme celý dokument, což v případě použití třídy XMLValidationReader zajistí vlastní validaci.

Poznámka : Schválně si vyzkoušejte změnit náš pokusný XML dokument do podoby, ve které nebude splňovat pravidla definovaná schématem (stačí změnit například jména tagů), abyste viděli, jaké validační chyby jsou hlášeny.

V tomto případě, kdy je umístění schématu (schemaLocation) v XML dokumentu definováno, XMLValidatingReader při validaci schémá z této lokace použije. Ovšem v situaci, kdy lokace XML schématu, není v dokumentu určena, máme samozřejmě možnost v našem kódu určit schéma nebo přesněji seznam schémat , podle kterých bude daný dokument validován.

public static void ValidaceDokumentUrcenimSchemat()
{
 XmlValidatingReader lValReader = new XmlValidatingReader(new XmlTextReader("C:/vyvojari_bezXSD.xml"));
 lValReader.ValidationType = ValidationType.Schema;
 //urceni lokace XML schematu pro dany jmenny prostor
 lValReader.Schemas.Add("
http://tempuri.org/Zamestnanci.xsd","C:/zamestnanci.xsd");
 lValReader.ValidationEventHandler += new ValidationEventHandler(lValReader_ValidationEventHandler);
 while(lValReader.Read()){}
 Console.WriteLine("Validace XML dokumentu dokoncena");
}

Programové určení schémat je realizováno pomocí instanční vlastnosti Schemas třídy XMLValidatingReader. Tato vlastnost je typu XMLSchemaCollection, která pomocí svého rozhraní umožňuje definovat seznam XML schémat, která mají být pro validaci použita. Pomocí jedné z přetížených verzí metody Add je do kolekce přidáno naše schéma pro daný XML jmenný prostor.

Soubory se zdrojovými kódy k příkladům se nacházejí zde.

Diskuze (1) Další článek: Uvolnění OpenOffice.org 2.0 odloženo

Témata článku: , , , , , , , , , , , , , , ,