Hatoljunk kicsit mélyebbre az XML adatok kezelésének néhány fontos módszerébe. Elsőként nézzük, hogyan lehet adatokat megkeresni az XML formátumban tárolt adatok között.
Vegyünk egy nagyon egyszerű XML adathalmazt, amelyben egy modern zöldséges tárolja a kínált gyümölcsökkel kapcsolatos legfontosabb adatokat:
<gyümölcsök>
<gyümölcs adat="valami">
<fajta>körte</fajta>
<szín>sárga</szín>
<ár>210</ár>
</gyümölcs>
<gyümölcs>
<fajta>alma</fajta>
<szín>piros</szín>
<ár>180</ár>
</gyümölcs>
<gyümölcs>
<fajta>szőlő</fajta>
<szín>kék</szín>
<ár>600</ár>
</gyümölcs>
<gyümölcs>
<fajta>barack</fajta>
<szín>piros-sárga</szín>
<ár>330</ár>
<egyéb>magbaváló</egyéb>
</gyümölcs>
<gyümölcskosár>
<gyümölcs>
<fajta>kivi</fajta>
</gyümölcs>
<gyümölcs>
<fajta>ananász</fajta>
</gyümölcs>
<ár>1200</ár>
</gyümölcskosár>
</gyümölcsök>
Látható, hogy vannak különálló gyümölcsök és gyümölcskosár részeként kapható gyümölcsök is. A szokásos módon beolvasom a fájlt és konvertálom XML adattípussá:
[13] PS C:\> $x = [xml] (Get-Content C:\_munka\powershell\OnLineTananyag\gyümöl
csök1.xml)
A gyümölcsök felsorolása az eddigi tudásunk alapján így nézne ki:
[14] PS C:\> $x.gyümölcsök.gyümölcs
adat fajta szín ár
---- ----- ---- --
valami körte sárga 210
alma piros 180
szőlő kék 600
barack piros-sárga 330
Azonban ebben csak a különálló gyümölcsök szerepelnek, a gyümölcskosár részeként elérhető gyümölcsök nem. Hogyan lehetne egyszerűen az összes gyümölcsöt felderíteni ebben az adathalmazban? Erre megoldást a Select-XML cmdlet és benne az XPath kifejezések megadásának lehetősége ad:
[15] PS C:\> $x | Select-Xml -XPath "//gyümölcs"
Node Path Pattern
---- ---- -------
gyümölcs InputStream //gyümölcs
gyümölcs InputStream //gyümölcs
gyümölcs InputStream //gyümölcs
gyümölcs InputStream //gyümölcs
gyümölcs InputStream //gyümölcs
gyümölcs InputStream //gyümölcs
Ez még nem tűnik annyira meggyőzőnek, de csak azért nem, mert a kimeneten egy összetett objektumgyűjteményt kapunk. A tényleges adatblokk a Node tulajdonság alatt húzódik meg, így fejtsük ki ezt:
[16] PS C:\> $x | Select-Xml -XPath "//gyümölcs" | Select-Object -ExpandPropert
y node
adat fajta szín ár
---- ----- ---- --
valami körte sárga 210
alma piros 180
szőlő kék 600
barack piros-sárga 330
kivi
ananász
Itt már látható, hogy tényleg az össze gyümölcsöt megkaptuk, a gyümölcskosár részeként megadottakat is. Ugyanezt a tulajdonság-megszólító jelölésrendszerrel nem tudtuk volna elérni. Az XPath tehát az XML adatok speciális lekérdező nyelve. A per-jelnek nagyon fontos szerepe van ebben a jelölésrendszerben, amit majd a későbbi példákban is látni fogunk. Itt a dupla per-jel azt jelenti, hogy bármelyik beágyazottsági szinten található gyümölcsöket keressük. Nagyon fontos, hogy az XPath kis-nagybetű érzékeny, így itt a ’gyümölcs’ nem véletlenül kisbetűs.
Ha csak a legfelső szint gyümölcsi érdekelnek, akkor ehhez így juthatunk el XPath-szal:
[17] PS C:\> $x | Select-Xml -XPath "gyümölcsök/gyümölcs" | Select-Object -Expa
ndProperty node
adat fajta szín ár
---- ----- ---- --
valami körte sárga 210
alma piros 180
szőlő kék 600
barack piros-sárga 330
De ennél természetesen jóval bonyolultabb dolgokat is tudunk művelni XPath segítségével. Például azokat a gyümölcsöket keresem, amiknek van ára:
[18] PS C:\> $x | Select-Xml -XPath "//gyümölcs[ár]" | Select-Object -ExpandPro
perty node
adat fajta szín ár
---- ----- ---- --
valami körte sárga 210
alma piros 180
szőlő kék 600
barack piros-sárga 330
Látszik, hogy a kivi és az ananász nem jött ki eredményként, hiszen azoknak nincs ára. A szögletes zárójelekben tehát azt lehet megadni, hogy ’van valamije’ a keresett objektumnak, azaz jelen esetben gyümölcsöket akarunk az eredményhalmazban látni, de olyanokat, amelyeknek van ára. Itt még tovább is mehetünk, azaz például keresem a 600 forintos gyümölcsöket:
[19] PS C:\> $x | Select-Xml -XPath "//gyümölcs[ár=600]" | Select-Object -Expan
dProperty node
fajta szín ár
----- ---- --
szőlő kék 600
Természetesen az egyenlőségjel mellett a többi összehasonlító operátort is lehet használni.
Eddig az XML csomópontokkal, ’node’-okkal dolgoztunk. Az XML-ben lehetnek még attribútum jellegű adatok is. A példafájlomban egy ilyet tettem be:
…
<gyümölcs adat="valami">
…
Az XPath kifejezésekkel ezekre is tudunk szűrni. Például azokat a gyümölcsöket keresem, amelyeknek van bármilyen attribútuma:
[20] PS C:\> $x | Select-Xml -XPath "//gyümölcs[@*]" | %{$_.node}
adat fajta szín ár
---- ----- ---- --
valami körte sárga 210
Az XPath szintaxisban a ’@’ jel utal az attribútumra, és a már ismert szögletes zárójel jelzi a birtokviszonyt. Az XPath tárháza természetesen itt még nem ér véget, különösebb magyarázat nélkül nézzünk néhány lehetőséget, azt hiszem a példák magukért beszélnek:
# Azokat keresem, amelyeknek 600 az ára vagy van attribútumuk
$x | Select-Xml -XPath "//gyümölcs[ár=600 or @*]" | %{$_.node}
# Van adat attribútuma
$x | Select-Xml -XPath "//gyümölcs[@adat]" | %{$_.node}
# adat = 'valami' (CASE SENSITIVE)
$x | Select-Xml -XPath "//gyümölcs[@adat='valami']"
# Ár nagyobb, mint 300
$x | Select-Xml -XPath "//gyümölcs[ár > 300]" | %{$_.node}