Áttekintés
Azt már bizonyára mindenki ismeri – aki elmélyedt valamelyest a .NET adatmanipulációs technikáiban - hogy miként lehet egy XML állomány tartalmát DataSet objektum segítségével beolvasni a memóriába, és feldolgozni, megjeleníteni.
Cikkünkben az XML–séma–adat „szentháromságának” egységével foglalkozunk, mint az adatábrázolás és megjelenítés magas fokú, hatékony formájával. Bemutatjuk, milyen elemekkel írja le egy XML séma az XML állományban elhelyezett adatok szerkezetét, és ezek ismeretében hogyan generálható egyik a másikból úgy, hogy közben nem kell elvesznünk a tagdefiníciók dzsungelében, hanem egy átgondolt, vizuális segédeszköz tudására hagyatkozva állíthatjuk elő ezeket az állományokat, tetszőleges felhasználási célra.
Az XML – mint ismeretes – jóval túlmutat azon, hogy az eddig relációs adatbázisokban tárolt információinkat egyik napról a másikra ebben a formátumban tároljuk, hiszen akkor lemondhatnánk az adatbázis-szoftverek logikája által biztosított védelmi mechanizmusról.
Az XML nem is ezt a célt kívánja elérni. Az XML segítségével egy jól körülhatárolt és megfelelően definiált szabályrendszert kapunk, melyben egzakt módon valósul meg a szűkebb értelemben vett adatkezelés. Mit is jelent ez a Visual Studio.NET rendszerben?
Az XML alapvetően két fő területet határoz meg az adattárolással kapcsolatban:
- A DataSet objektumban (mint memóriabeli cache-ben) tárolt adathalmazok szerializációja XML állományba. A DataSet objektumban tárolt adatok sémája - táblái, oszlopai, típusai, megszorításai – egy XML séma állományban vannak definiálva (.XSD).
- Az adattároló objektumok és sémák közötti konverzió lehetőségének megteremtése, vagyis létező XML séma felhasználásával DataSet generálása, valamint ennek fordítottja.
Az XML Designer segítségével mindezt egyszerre, egyszerűen tehetjük meg. XML sémákat, ADO.NET DataSet-eket, XML állományokat és forrásfájlokat is generálhatunk (ahogy később látni fogjuk).
Az eszköz segítségével három módon szerkeszthetjük adatainkat:
- Séma nézet: az XML sémák elemeit reprezentáló vizuális (ToolBox-ról levehető) komponensekkel szerkeszthetjük a DataSet objektumokat és az XML séma állományokat.
- Adat nézet: strukturált DataGrid objektumokban adhatunk meg értékeket az XML adatállományokhoz.
- XML nézet: színes forráskódot van lehetőségünk szerkeszteni, manuálisan eszközölve bejegyzéseket az állományokban. Itt használhatjuk az IntelliSence és automatikus adat-kiegészítés technikáját.
XML sémák
A szabvány szerint az XML sémák az XML állományokban elhelyezett adatok struktúráját és alkotóit vannak hivatva definiálni és érvényesíteni.
Az XML sémák ezen funkciója az XML séma definíciós nyelv (XML Schema Definition Language: XSD) felhasználásával valósul meg. Az XSD nyelvi elemei (elemek, attribútumok, típusok és csoportok) segítségével definiálja a megfelelő struktúrát, a megfelelő adattartalmat és az egyes adattípusok közötti kapcsolatokat. Az elemek és attribútumok esetén alapértelmezett értékeket is definiálhat.
Az XML séma használatával garantálható az egyes XSD típusok közötti konzisztencia, még akkor is, ha az adott adathalmaz különböző alkalmazások és szervezetek között megosztva használatos. Az egyes szervezetek kibocsáthatnak sémákat, melyek leírják az általuk használt alkalmazások által generált, vagy felhasznált XML-ek formátumát. Más szervezetek és alkalmazások, melyek kommunikálni és adatot cserélni szeretnének a fenti alkalmazással, elegendő, ha a kibocsátott, publikus séma köré építik az adatcserét megvalósító alkalmazást, és az XML alapú üzenetek értelmezhetőek lesznek. Erre a legjobb példa az XML alapú Web szervizek technológiája, ahol az üzenetváltás alapját képező SOAP szabvány az XML-re épül, és a Webes alkalmazást anélkül használhatjuk, hogy ismernénk a konkrét kódot. Elegendő az alkalmazás WSDL sémáját ismernünk ehhez.
A Visual Studio.NET rendszer teljes egészében támogatja az XML sémák felhasználását. Az XML sémák maximálisan követik a W3C szabványügyi konzorcium vonatkozó ajánlásait, melyek az XSD-ben öltenek testet.
Csak néhány előny a sok közül, melyek miatt érdemes az XML sémákat használni:
- Az adatdefiníciós nyelv szintaxisa XML alapú, így nincs szükség új nyelv elsajátítására az adatszerkezetek definiálásakor.
- Az XML sémák támogatják az újrafelhasználható típusokat, vagyis új típusok hozhatók létre a meglévők tulajdonságait örökölve.
- Támogatja az elemek csoportba szervezését, melynek segítségével kontrollálhatja az egyes elemek és típusok ismétlődését.
A következő szakaszokban az XML séma nyelvi elemeivel ismerkedhetünk meg.
XSD elemek
Az XSD alapvető elemei az ELEMENT és az ATTRIBUTE elemek, az egyszerű és összetett típusok ezek felhasználásával hozhatók létre. A definíciókban a létrehozott elemekhez adunk meg típusokat, és alapértékeket. Az ELEMENT tagok meghatározzák az egyes adatmezők nevét és típusát, míg az attribútumok az elemek property-jeiként értelmezhetők. Ezeket használhatjuk a magasabb szintű absztrakciók jellemzésére (osztályok, struktúrák esetén).
Lássunk egy példát az ELEMENT alkotó használatára:
<xs:element name="Name" type="xs:string" />
Az általa reprezentált adat jellemzője, hogy neve Name és típusa string. Ennek XML állománybeli megvalósulása a következő lehet:
XSD attribútumok
Az attribútumok névvel rendelkező egyszerű-típus definíciók, melyek nem tartalmazhatnak más elemet. Ezek használhatóak az ELEMENT összetevők esetén megadható alapértelmezett érték jelzésére, egy komplett típusdefiníció végén.
A következő sorok példázzák az attribútumok használatát:
<xs:element name="OrderInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="CustomerName" type="xs:string" />
<xs:element name="OrderNumber" type="xs:positiveInteger" />
<xs:element name="OrderTotal" type="xs:number" />
</xs:sequence>
<xs:attribute name="OrderDiscount" type="xs:number" />
</xs:complexType>
</xs:element>
Néhány fontos momentum a fenti elemek használatával kapcsolatban:
- A nevek használatánál figyelembe kell venni a feldolgozó kis-nagybetű érzékeny működését.
- Az attribútumokban értékadásakor idézőjelet kell használni.
- Az ELEMENT tagok nevei nem kezdődhetnek számmal, „_” jellel, vagy az XML szócskával.
- A nevek nem tartalmazhatnak szóközt.
XSD Adattípusok
A típusok lehetnek egyszerű, összetett típusok és a felhasználó által deklarált típusok. Az összetett típusok az egyszerű típusokból épülnek fel. A típusok használandóak az ELEMENT és ATTRIBUTE tagokban.
A típusok tartalmazhatnak módosító elemeket is, melyek meghatározhatják az adott elem típusának maximális értékét. Lássunk erre egy példát:
<xs:simpleType name="qtyLimiter">
<xs:restriction base="xs:positiveInteger">
<xs:maxInclusive value="100" />
</xs:restriction>
</xs:simpleType>
Az <xs:maxInclusive> tag határozza meg az egyszerű típusban megadható maximális értéket.
Példa séma létrehozása
A példában található egy CListSchema.xsd nevű állomány, mely definiálja a CList.xml állomány adatainak szerkezetét. Lássuk, hogyan használhatjuk létrehozásához az XML Designer-t.
Az adathalmaz egy ügyféllistát (<customerList>) reprezentál, melyben ügyfél-objektumok (<Customer>) találhatók. Minden ilyen tartalmazza az ügyfél adatait (egyszerű típusok), valamint két összetett típust, melyek egyike a szállítás helye, másik a számla fejlécének adatait írja le.
A projekthez első lépésként adnunk kell egy XML séma állományt, majd el kell neveznünk CListSchema.xsd-nek. A séma szerkesztőpaneljére a ToolBox-ról elemeket vonszolhatunk át, melyek egy-egy nyelvi elemet jelképeznek.
Elsőkét létre kell hozni egy postalCode nevű egyszerű típust, mely majd minden egység irányítószám adatát tartalmazza. Ehhez egy sympleType komponenst kell a panelre vonszolni. Az XML nézetben meg is nézhetjük a kódot, mely a következő lesz:
<xs:simpleType name="postalCode">
<xs:restriction base="xs:positiveInteger">
<xs:pattern value="\d" />
</xs:restriction>
</xs:simpleType>
A panelen egy DataGrid jelenik meg, ahol beállíthatjuk a típus nevét, valamint mezőket adhatunk hozzá, típussal.
Következő lépés egy összetett típus létrehozása a címadatok tárolásához. Ehhez egy complexType elemre van szükség, majd meg kell adni a mezőket, melynek eredménye a következő XML kód:
<xs:complexType name="addressType">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Street" type="xs:string" />
<xs:element name="City" type="xs:string" />
<xs:element name="State" type="xs:string" />
<xs:element name="Zip" type="postalCode" />
</xs:sequence>
</xs:complexType>
A típus mezőinek adatai a következők:
| Elem neve |
Típusa |
| Street |
string |
| City |
string |
| State |
string |
| Zip |
postalCode |
A következő lépés egy ügyfél-objektum létrehozása, mely a Customer nevet viseli, és egy element komponens jelképezi. Mezőinek beállítása után egy létrehozunk még egy element komponenst customerList néven, majd ebbe belevonszoljuk a Customer elemet, jelezve, hogy az előbbi az utóbbiak listáját tartalmazza. A végén az egész eredménye a következő kód:
<xs:element name="customerList">
<xs:complexType>
<xs:sequence>
<xs:element name="Customer">
<xs:complexType>
<xs:sequence>
<xs:element name="CompanyName" type="xs:string" />
...
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Az egyes objektumok közötti kapcsolatot grafikusan ábrázolja a panel.
A séma elkészülte után a CList.xml állományhoz kapcsoljuk úgy, hogy az állomány tulajdonságlapján a targetSchema property értékét kiválasztjuk a listából. Ez a következő lesz:
http://tempuri.org/CListSchema.xsd
Az XML állomány fejlécében megjelenik a hivatkozás a sémára:
<customerList xmlns="http://tempuri.org/CListSchema.xsd">
Az XML adatnézetében egy rácsban szerkesztve adhatunk adatokat az állományhoz.
A séma szerkesztőnézetének gyorsmenüjéből kiválaszthatjuk, hogy egy DataSet forrásállományt generáljon az IDE a projektünkhöz. Ekkor egy osztály jön létre, mely a DataSet osztályból származik és példányosítható az alkalmazásban.
Az állomány CListSchema.cs néven jön létre, és a származtatott osztály neve customerList lesz.
A program betöltődésekor létre is hozunk egy példányt, melyet adatforrásként átadunk a DataGrid kontrolnak, miután betöltöttük a CList.xml állományt.
customerList cSet = new customerList();
cSet.ReadXml("CList.xml");
dataGrid1.DataSource = cSet.Tables[0].DefaultView;