Nem vagy bejelentkezve. Ha bejelentkezel, további menüpontokat érhetsz el. Ha még nincs felhasználóneved és jelszavad, itt regisztrálhatsz.


Kezdőoldal  ---- Blog Témakörök  --- XML  ---- XML fájlból adatbázisba 1. rész
2010.01.01
XML fájlból adatbázisba 1. rész

Adott a következő feladat: egy hosszú és összetett XML fájlt kell relációs adatbázisba tenni. Természetesen XSD is van hozzá. Többféle lehetőség is kínálkozik, a cikksorozat ezeket fogja sorban elemezni:

1. XML feldolgozása DataSet segítégével

Létrehozunk egy dataset objektumot, megadjuk neki a sémát, majd egyszerűen beleolvassuk az XML fájlt:

Dim dsXML As DataSet
dsXML.ReadXmlSchema(xsd_doksi)
dsXML.ReadXml(xml_doksi, XmlReadMode.ReadSchema)

Ezzel létrejön a dataset objektum a memóriában, sok-sok táblával (ha elég összetett volt a forrás xml, de általában elég összetett).

Ha ezt a datasetet megadjuk egy datagridview objektum forrásának, akkor bele is kukkanthatunk az eredménybe, ha megadjuk a datagridview forrásának a dataset valamelyik tábláját.

DataGridView1.DataSource = dsXML.Tables(0)

majd

DataGridView1.DataSource = dsXML.Tables(1)
...stb.

Az eredmény: szépen látszódnak a táblák amiket készített. A baj az, hogy a forrás XML bizony sok keresztbe-kasul relációt is tartalmazott, amik sajnos nem látszanak. A relációkat a friss táblák úgy őrizték meg, hogy belepakolt a mezők mellé plusz mezőket, amik "_Id" végződésű neveket kaptak.
Valamiért annak ellenére hogy benne vannak ezek az automatikusan létrejött "segéd" _Id mezők, nem jelennek meg a datagridview automatikus nézetében. Ha mindenképp látni szeretnénk, némi rábeszélésre egy textboxban ki tudjuk iratni őket:

DataGridView1.DataSource = dsXML.Tables(0)
For i = 0 To dsXML.Tables(0).Columns.Count - 1
TextBox1.Text = TextBox1.Text & vbCrLf & " " & dsXML.Tables(0).Columns(i).ColumnName
Next

Így láthajuk, hogy mindenféle _Id végződésű mezőt pakolt hozzá a datagridview oszlopaihoz, így próbálva a relációkat valahogy megőrizni.
Ezzel két problémám van:

1. Nyomokban sincs köze a szerkezetnek az XSD fájlban definiált szerkezethez, márpedig az adatbázis, amibe majd tenni kell az adatokat, illendő lenne, ha olyan szerkezetű lenne, ahogyan ezt az XSD előírta. A dataset táblanevei a nodoknak felelnek meg, és nem az xsd fájlban definiált struktúrának. (Ez persze várható volt, de reménykedtem...)
2. Követhetetlenek a relációk.

Ez a megoldás valószínűleg kiválóan működik egy olyan XML fájlra, ahol sok egyforma, de nem túl összetett szerkezetű adat van. Például erre az xml-re:

<Autok>
<Auto>Trabant</Auto>
<Auto>Mercedes</Auto>
</Autok>

Nagyszerűen működik, pont azt látom a gridben amit kell - de az élet sajnos nem ilyen XML fájlokat sodor a közelünkbe, hanem hosszú, bonyolult, ismétlődő, egymásba ágyazott, keresztbe hivatkozó, stb.
Próbáljuk meg a relációkat valahogy tudomására hozni a datasetnek, hogy barátságosabb formában láthassuk a datagridview-ban az adatokat. Van két táblánk a datasetben, a mezo_Id a közös bennük, és a két tábla összekapcsolásával szeretnénk kiíratni néhány mezőt:

Dim egyiktabla = dsXML.Tables("egyiktabla").AsEnumerable()
Dim masiktabla = dsXML.Tables("masiktabla").AsEnumerable()

Dim vegyesnezet = egyiktabla.Join(masiktabla, Function(masik) masik.Field(Of Object)("mezo_Id"), _
Function(egyik) egyik.Field(Of Object)("mezo_Id"), _
Function(egyik, masik) _
New With {.eredmenymezo1 = egyik.Field(Of Object)("mezonev1"), .eredmenymezo2 = egyik.Field(Of Object)("mezonev2")})

És végül adjuk meg a lekérdezést a datagridview forrásának, hogy láthassuk az eredményt:

DataGridView1.DataSource = vegyesnezet.ToList

Arra nagyon figyelnünk kell, hogy a típusokat helyesen adjuk meg(a Field(Of [típus]) esetében), mert ha a típus nem megfelelő, akkor csak hibaüzenetet fogunk kapni.

Remek példa van az MSDN-en erről itt is: http://msdn.microsoft.com/en-us/vbasic/bb738025.aspx
Egyetlen gondom volt vele, mégpedig ezzel az utasítással:

ObjectDumper.Write(smallOrders)

Ez az ObjectDumper ugyanis semelyik névtérben nem leledzett nálam, némi utánajárás után kiderült, hogy ez egy spéci osztály, ami letölthető. Le is töltöttem, de órák alatt sem sikerült munkára bírnom, meg a kódomba sem szerettem volna beemelni mindenféle kódnövesztőt, az ObjectDumper irodalma is elég szerény, így addig kísérleteztem, amíg sikerült kiküszöbölnöm a használatát, mégpedig a

.ToList

utasítással.  (Biztosan vesztettem ezzel nagyon jó dolgokat amiket az ObjectDumper tud, a ToList meg nem, de még nem jöttem rá mik ezek, én elégedett voltam a látvánnyal ami a DataGridView-ban megjelent)

Ha ezzel a módszerrel addig gyűrjük a datasetet, amíg pontosan azokat a relációkat csikartuk ki belőle, ahogyan majd az adatokat bele akarjuk tenni az adatbázisba, akkor egy ilyen lekérdezés eredményét már könnyedén beletehetjük egy (vagy több) SQL utasítással az adatbázisba.

Kulcsszavak:
dataset xml xsd

További cikkek:

  Hozzászólások
Hozzászólás a cikkhez:
Ide írhatsz: