Keresés az XML adatok között (Select-XML és az XPath)

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}



Word To HTML Converter