Kurs: XML tehnologije i veb servisi
Modul: XML tehnologije
Autor: Vladimir Marić
Naziv jedinice: Korišćenje XSD šema
Materijali vezani uz ovu lekciju:
-
Test korišćenje xsd šema -
Korišćenje XSD šema (PDF dokument)
Da bismo izbegli preklapanje istoimenih, ali raznornodnih XML struktura jednog dokumenta, između ostalog, možemo koristiti i prostore imena. Prostori imena obezbeđuju kontekstualni integritet podataka koji se u njemu nalaze.
Na primer:
<root>
<kartica>
<naziv>visa virtuon</naziv>
<naziv>visa elektron</naziv>
<naziv>master card</naziv>
</kartica>
<kartica>
<proizvodjac>msi</ proizvodjac>
< proizvodjac >asus</proizvodjac>
<proizvodjac>intel</proizvodjac>
</kartica>
</root>
Ovaj XML dokument sadrži podatke o karticama, ali njegovi elementi, ustvari, nose potpuno različite tipove podataka. Jedan element sadrži platne kartice, a drugi grafičke. Ipak, parser ne bi bio u stanju da vidi razliku između ovih tipova i svi podaci bi bili tretirani na jedan isti način. Zbog toga, ova dva tipa podataka možemo razdvojiti prostorima imena:
<root>
<platne:kartica xmlns:platne="platneKartice">
<platne:naziv>visa virtuon</platne:naziv>
<platne:naziv>visa elektron</platne:naziv>
<platne:naziv>master card</platne:naziv>
</platne:kartica>
<graficke:kartica xmlns:graficke="grafickeKartice">
<graficke:proizvodjac>msi</graficke:proizvodjac>
<graficke:proizvodjac>asus</graficke:proizvodjac>
<graficke:proizvodjac>intel</graficke:proizvodjac>
</graficke:kartica>
</root>
Vidimo da je dodato nekoliko komponenti prethodnom XML dokumentu.
Svaki element (podelement) sadrži prefiks odvojen dvotačkom od naziva elementa. U prvom setu, to je platne, a u drugom grafičke. Ovo nam omogućava da stavimo željene elemente u željene prostore imena.
xmlns:platne="platneKartice" – Ovo je deklaracija prostora imena: xmlns: (ključna reč koja označava početak deklarisanja prostora imena), platne (prefiks prostora imena (ovaj prefiks mora se poštovati u nazivima elemenata)), ="platneKartice" (Identifikator prostora imena. Nije bitno šta će ovde pisati, sve dok je unikatno na nivou dokumenta, jer ćemo se na osnovu ovog imena kasnije obraćati prostoru imena. Najčešće se, kao identifikator prostora imena, unosi veb lokacija na kojoj se nalazi opis tog prostora imena).
Čitanje prostora imena može se ostvariti na različite načine. Koristeći XmlDocument, ovaj proces je vrlo jednostavan:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"c:\mojXml.xml");
XmlNodeList xmlnl = xmlDoc.GetElementsByTagName("kartica","grafickeKartice");
foreach(XmlElement xe in xmlnl)
Console.WriteLine(xe.InnerText);
Pod pretpostavkom da promenljiva xmlDoc sadrži XML dokument iz prethodnog primera, sve elemente jednog prostora imena možemo izvući prosleđivanjem još jednog parametra u metod za pretragu (GetElementsByTagName). Ova metoda vraća sve podelemente jednog elementa, ali može prihvatiti i opcioni parametar - Namespace. U tom slučaju, za vraćanje svih podelemenata, moraće da bude ispunjen jedan uslov – poklapanje prostora imena navedenog kao parametar sa nekim od postojećih prostora imena.
Osim unutar elemenata, prostore imena je moguće definisati i u samom korenu dokumenta. Tada, postavljamo sve definicije prostora imena jednu za drugom, kao zasebne atribute korenog elementa:
<root xmlns:platne="platneKartice" xmlns:graficke="grafickeKartice">
<platne:kartica >
<platne:naziv>visa virtuon</platne:naziv>
<platne:naziv>visa elektron</platne:naziv>
<platne:naziv>master card</platne:naziv>
</platne:kartica>
<graficke:kartica >
<graficke:proizvodjac>msi</graficke:proizvodjac>
<graficke:proizvodjac>asus</graficke:proizvodjac>
<graficke:proizvodjac>intel</graficke:proizvodjac>
</graficke:kartica>
</root>
Prostor imena je na više načina moguće uneti u dokument. Na primer, prilikom kreacije XmlDocument dokumenta, jednostavno treba dodati prostor imena u LoadXml metodi:
xmlDoc.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>
<root xmlns:platne="platneKartice" xmlns:graficke="grafickeKartice"></root>");
Ili na nivou samih elemenata:
XmlElement izdanje =
xmlDoc.CreateElement("mojPrefix", "izdanje", "http://mojasema.com");
Nakon prethodne linije, svi elementi izdanje, imaće sledeću strukturu:
<mi:izdanje id="1" isbn="Predeo slikan cajem" xmlns:mi="http://www.mojaSema.com">
XSD šema
XSD šema je sistem za predstavljanje strukture XML dokumenta.
Vratimo se na primer sa knjigama:
<?xml version="1.0" encoding="UTF-8"?>
<izdanja>
<izdanje id="1" isbn="1111" >
<autor>Milorad Pavic</autor>
<naslov>Predeo slikan cajem</naslov>
</izdanje>
<izdanje id="2" isbn="2222" >
<autor>Milorad Pavic</autor>
<naslov>Predeo slikan cajem</naslov>
</izdanje>
</izdanja>
Recimo da želimo da ovaj dokument bude validan, prema određenoj XSD šemi. Ova šema mogla bi izgledati ovako:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="izdanja" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="izdanja" >
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="izdanje">
<xs:complexType>
<xs:sequence>
<xs:element name="autor" type="xs:string" minOccurs="0" />
<xs:element name="naslov" type="xs:string" minOccurs="0" />
</xs:sequence>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="isbn" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Da bi se XML dokument pozivao na određenu šemu, potrebno je da u samom dokumentu unesemo referencu na tu šemu.
<izdanja xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="mojaSema.xsd" >
Ako hoćemo da programabilno izvršimo validaciju dokumenta prema šemi, možemo to uraditi uz pomoć XmlTextReader i XmlValidationReader klasa:
//preuzimamo xml dokument
XmlTextReader xmlDoc = new XmlTextReader(»mojXml.xml«);
//kreiramo instancu klase XmlValidatingReader
XmlValidatingReader validator = new XmlValidatingReader(xmlDoc);
//Kažemo da želimo da vršimo validaciju nad šemom
validator.ValidationType = ValidationType.Schema;
//Kreiramo instancu instancu klase XmlSchemaCollection
XmlSchemaCollection c;
c = validator.Schemas;
//Dodajemo šemu kolekciji
c.Add(null, “mojaSema.xsd”);
//Dodeljujemo event handler na validator
validator.ValidationEventHandler += new ValidationEventHandler(greska);
//Prolazimo kroz dokument uz pomoć validatora
while(validator.Read()) ;
Da bi primer bio validan, potreban nam je i odgovarajući rukovalac događajima:
public static void greska(object s, ValidationEventArgs a)
{
Console.WriteLine(a.Message);
}
Ovaj program će, ukoliko je šema dobra biti izvršen bez poruka.
Xsd.exe
Ovo je multifunkcionalni alat za rukovanje XML dokumentima, odnosno, XSD šemama.
Naime, iako je dobro poznavati sintaksu XSD šeme, ovo nije neophodno, jer se one najčešće generišu uz pomoć alata. Jedan od njih je i xsd.exe. Xsd.exe je u stanju da napravi XSD šemu na osnovu XML dokumenta. Ovaj alat ne mora biti podrazumevano u sklopu Visual Studio-a pa ga je ponekad potrebno zasebno preuzeti. Ukoliko je prisutan na sistemu, nalazi se u folderu:
C:\Program Files\Microsoft Visual Studio X\SDK\vX\Bin\
Da bismo napravili šemu na osnovu XML dokumenta, potrebno je samo da aktiviramo aplikaciju sa XML dokumentom kao parametrom:
xsd mojXml.xml
U istom folderu, dobićemo istoimeni fajl sa XSD ekstenzijom (mojXml.xsd).
Pored šeme, uz pomoć xsd.exe alata možemo kreirati i samu klasnu strukturu. Procedura je takođe jednostavna. Pored postojeće naredbe, potrebno je još dodati i prekidač /classes i /language:cs.
xsd mojaSema.xsd /classes /language:cs
U istom folderu, biće kreiran dokument mojaSema.cs sa kompletnim objektnim modelom za zadatu šemu.
Najvažnije iz lekcije:
Prostori imena u XML-u služe za razdvajanje različitih struktura istog imena.
Prostor imena definiše se atributom xmlns.
Atribut za definiciju prostora imena nalazi se na elementu na koji se prostor imena odnosi ili na korenom elementu dokumenta.
Moguće je definisati više različitih prostora imena na jednom korenom elementu dokumenta.
XSD šema sadrži strukturu nekog XML dokumenta.
Da bi dokument bio validan prema šemi, moramo izvršiti njegovu validaciju.
XSD šeme je moguće kreirati ručno ili uz pomoć alata.