Redgate Hub

  • XML-tietojen käyttäminen PowerShellissä
    • Accessing XML with XPath.
    • XML:n käyttäminen objekteina.
    • XPath- ja objektilähestymistapojen vertailu
  • XML-tietojen muokkaaminen tai luominen
    • XML-tietojen lisääminen
    • XML:n käyttäminen objektien sarjallistamiseen

Sisällysluettelo

Mikä tahansa muukin korkeatasoisen kielen tavoin, PowerShellin ytimessä the data on the data. PowerShellin tapauksessa tämä tiivistyy ulkoisten tietojen muuntamiseen PowerShell-objekteiksi ja päinvastoin. Tämä on toinen osa artikkelisarjasta, jossa kerrotaan, miten tuot lähes kaikkia tavallisia dataformaatteja, joihin todennäköisesti törmäät, ja miten viet niitä myös joihinkin niistä. Sarjan ensimmäinen artikkeli, PowerShell Data Basics: Tiedostopohjaiset tiedot, käsittelee erilaisia tekstimuotoja kiinteän leveyden, vaihtelevan leveyden ja oikeanpuoleisen reunan tiedostoista CSV-tiedostoihin, ominaisuusluetteloihin, INI-tiedostoihin ja JSON-tietoihin, ja lopuksi käsitellään tuontia ja vientiä Exceliin. Tässä keskitytään siihen, miten XML:stä saadaan paras mahdollinen hyöty irti.

XML-tietojen käyttäminen PowerShellissä

XML-tietojen käsittelyyn PowerShellissä on kaksi sisäänrakennettua tekniikkaa: XPath-lähestymistapa ja objektipistemerkintämenetelmä. Kuvaamme ja vertailemme näitä kahta lähestymistapaa ja kokeilemme niitä joillakin XML-näytteillä. Kaikissa koodiesimerkeissä käytetään kätevyyden vuoksi tätä MSDN:n XML-näytetiedostoa. Kuvassa 1 on Visual Studion XML Schema Explorerin tarjoama esitys tiedoston perustana olevasta skeemasta tiiviissä muodossa (erityisesti verrattuna raa’an XSD-tiedoston lukemiseen!). Kuvasta huomaat, että XML-tiedosto on luettelo, joka sisältää kokoelman kirjoja. Jokaisella kirjalla on seitsemän ominaisuutta, joista kuusi on lapsielementtejä ja yksi on lapsiattribuutti.

Kuvio 1 Microsoftin XML-esimerkkitiedoston skeemao:p>

Tämän XML-esimerkkitiedoston lataamiseen voit käyttää mitä tahansa näistä:

jos haluat mieluummin kokeilla välitöntä XML-tiedon käsittelyä sen sijaan, että lataisit XML-tiedoston XmlDocumentiin, se on helppoa. Määrittele vain XML-tietosi merkkijonoksi ja muunna se XML-tyypiksi, kuten juuri teimme tiedostojen Get-Content-cmdletillä. Tässä on osa esimerkin XML-tiedostosta, jossa on vain kaksi kirjaa:

Accessing XML with XPath

Kun tiedosto on ladattu XmlDocument-olioon, voit sitten navigoida XML-puussa XPathin avulla. Voit valita joukon solmuja SelectNodes-metodilla:

$xdoc.SelectNodes(”//author”)

#text

Gambardella, Matthew

Ralls, Kim

Corets, Eva

Corets, Eva

Randall, Cynthia

Thurman, Paula

Knorr, Stefan

Kress, Peter

O’Brien, Tim

O’Brien, Tim

Galos, Mike

Tai palauttaaksesi vain yhden solmun voit käyttää komentoa SelectSingleNode:

$xdoc.SelectSingleNode(”//book”)

id : bk102

author : Ralls, Kim

otsikko : Midnight Rain

genre : Fantasia

hinta : 5.95

publish_date : 2000-12-16

description : Entinen arkkitehti taistelee yritysten zombeja,

pahaa velhoa ja omaa lapsuuttaan vastaan tullakseen maailman kuningattareksi

.

Huomaa ensimmäisessä esimerkissä, että siinä on kaksoiskappaleita. Oletetaan sen sijaan, että haluat luettelon luettelossa olevista uniikeista kirjailijoista. Saatat ajatella, että jotain …

1
$xdoc.SelectNodes(”//author”) | select -Unique

…toimisi, mutta itse asiassa se palauttaa vain ensimmäisen tekijän nimen. Ymmärtääksesi, miksi se epäonnistui, sinun pitäisi ymmärtää enemmän XML-dokumenttien rakenteesta. Ensimmäinen esimerkki palautti itse asiassa tekstisolmujen luettelon (ei siis tekstiluetteloa), ja uniikkisuodatin toimii tuossa luettelossa etsien elementtityypin yksikäsitteisyyttä. Koska kaikki kokoelman kohteet ovat tekstisolmuja ja siten kaikki ovat samaa elementtityyppiä, kaikki ensimmäisen solmun jälkeiset solmut katsotaan kaksoiskappaleiksi. Tuloksena on, että vain ensimmäinen palautetaan.

Mitä oikeastaan etsit, on kunkin kirjoittaja-solmun merkkijonoarvo. Kirjoittaja-solmusta on ensin käytettävä sen tekstisolmua (sen ensimmäinen ja ainoa lapsi) ja sitten kyseisen tekstisolmun arvoa (seuraavassa esimerkissä rivi A). Vaihtoehtoisesti voit käyttää hieman lyhyempää lauseketta InnerText-ominaisuudella (rivi B). Vielä yksi variaatio käyttää Select-Xml-cmdletiä, jolla vältetään metodikutsu ja joka on siten jossakin mielessä selkeämmin PowerShell-lähestymistapa (rivi C). Kaikki kolme riviä palauttavat saman tuloksen.

SelectNodes ja SelectSingleNode yhdessä antavat Select-Xml:ää vastaavan toiminnallisuuden. Molemmat tukevat nimiavaruuksia, joita en ole vielä maininnut. Molemmat metodit ottavat molemmat XmlNamespaceManagerin valinnaisena toisena parametrina, kun taas Select-Xml-cmdlet ottaa valinnaisen Namespace-parametrin, joka määrittää nimiavaruudet hash-taulukkona.

SelectSingleNode palauttaa XmlNoden ja SelectNodes palauttaa XmlNodeList. Select-Xml puolestaan palauttaa SelectXmlInfo-olion (tai niiden joukon) ja sen Node-ominaisuus antaa pääsyn taustalla olevaan solmuun. Juuri yllä oleva esimerkki havainnollistaa näitä eroja.

XML:n käyttäminen objekteina

Samoin kuin edellisessä jaksossa käytetyllä XmlDocument-objektilla PowerShell tarjoaa myös dynaamisen objektituen XML-tiedoille: Näin voit käyttää XML-dataa ensimmäisen luokan PowerShell-objekteina, mikä ei vaadi XPath-valitsinta eikä perehtyneisyyttä esimerkiksi XML-solmujen, arvojen tai tekstisolmujen yksityiskohtiin. Lisäksi saat välittömästi XML-skeeman dynaamisen älykkyyden, kun lataat XML-tietojasi! Kuva 2 havainnollistaa tätä PowerShell ISE:n osalta, jossa saat sekä valintavaihtoehdot että sanan täydennyksen, aivan kuten PowerShellin natiivien merkkien kanssa. Huomaa erityisesti alimmassa laajennuksessa, että se etsii, mitä olet kirjoittanut missä tahansa ominaisuuden nimessä, eikä vain ensimmäisestä merkistä alkaen: Intellisense löytäisi täältä päivämääräominaisuuden, oli sen nimi sitten published_date tai releaseDate tai date_of_publication. Huomaa, että sinulla on word completion käytettävissä PowerShell V2:ssa tai V3:ssa sekä PowerShell ISE:ssä tai PowerShell-konsolissa. Valintavaihtoehdot ovat kuitenkin käytettävissä vain PowerShell ISE:ssä V3:ssa.

Kuva 2 Automaattinen Intellisense XML-dokumenttia ladattaessa

Seuraavassa on muutamia esimerkkejä, jotka osoittavat, että XML todellakin muunnetaan automaattisesti PowerShell-objekteiksi:

$xdoc

xml catalog

– —

version=”1.0″ catalog

$xdoc.catalog

book

{book, book, book, book, book…}

$xdoc.catalog.book | Format-Table -AutoSize

id author title title genre price publish_date description

– — — — — — —- —- —-

bk101 Gambardella, Matthew XML Developer’s Guide Tietokone 44.95 2000-10-01 Perusteellinen katsaus …

bk102 Ralls, Kim Midnight Rain Fantasy 5.95 2000-12-16 Entinen arkkitehti…

bk103 Corets, Eva Maeve Ascendant Fantasy 5.95 2000-11-17 Romahduksen jälkeen…

bk104 Corets, Eva Oberonin perintö Fantasy 5.95 2001-03-10 Maailmanlopun jälkeisessä…

bk105 Corets, Eva Sundered Grail Fantasia 5.95 2001-09-10 Kaksi tytärtä…

bk106 Randall, Cynthia Rakastava lintu Romanssi 4.95 2000-09-02 2000-09-02 Kun Carla tapaa …

bk107 Thurman, Paula Splish Splash Romanssi 4.95 2000-11-02 Syvänmeren sukeltaja …

bk108 Knorr, Stefan Creepy Crawlies Kauhu 4.95 2000-12-06 Antologia h…

bk109 Kress, Peter Paradox Kadonnut tieteiskirjallisuus 6.95 2000-11-02 Sen jälkeen, kun epähuomiossa …

bk110 O’Brien, Tim Microsoft .NET: The Prog… Tietokone 36.95 2000-12-09 Microsoftin .NET …

bk111 O’Brien, Tim MSXML3: A Comprehensive … Tietokone 36.95 2000-12-01 The Microsoft MSX…

bk112 Galos, Mike Visual Studio 7: A Compr… Tietokone 49.95 2001-04-16 Microsoft Visual …

$xdoc.catalog.book

id : bk103

tekijä : Corets, Eva

nimeke : Maeve Ascendant

genre : Fantasia

hinta : 5.95

publish_date : 2000-11-17

description : Nanoteknologia

yhteiskunnan romahdettua Englannissa nuoret eloonjääneet luovat

perustan uudelle yhteiskunnalle

$xdoc.catalog.book.author

Randall, Cynthia

$xdoc.catalog.book.id

bk106

Huomaa, että kaikki asiakirjan XML-solmut muunnetaan tavallisiksi PowerShell-ominaisuuksiksi riippumatta siitä, onko solmulla lapsia (esim. catalog) vai onko se lehtisolmu (esim. price) tai onko lehtisolmu elementti (esim. author) vai määrite (esim. id). Erityisesti (kuten kaksi viimeistä esimerkkiä yllä havainnollistavat), elementtiarvoja ja attribuuttiarvoja käsitellään täsmälleen samalla tavalla tavallisella ”piste”-merkintätavalla.

Comparison of XPath and Object Approaches

Comparison of XPath and Object Approaches

Kumpi lähestymistapa on parempi XML-tiedon käyttämiseen? Taulukko 1 auttaa sinua vastaamaan tähän kysymykseen. Objektilähestymistapa on yleensä tiiviimpi (esim. rivi 3), mutta ei aina (rivi 4). XPath on kuitenkin ilmaisuvoimaisempi sikäli, että sen avulla voidaan määritellä joitakin valitsijoita, jotka eivät ole mahdollisia objektin merkintätavalla (rivi 7). PowerShellin omat ominaisuudet voivat kuitenkin helposti täyttää tämän aukon, kun käytetään objektinotaatiota (rivi 8).

Taulukko 1 XPath- ja objektivalitsimien lähestymistapojen vertailu XML-käytössä.

XML-tiedon muokkaaminen tai luominen

Mikäli XML-selektoreiden arvostus on saatu edellisistä kappaleista, XML-dokumentin muokkaaminen on melko suoraviivaista, koska XML-selektorit (XPath- tai objekti-selektorit) ovat L-arvoja, eli niihin voi kirjoittaa sekä kirjoittaa että lukea niistä! Näin ollen jompikumpi näistä muuttaa kuudennen kirjan kirjoittajaa:

1
2

$xdoc.SelectSingleNode(”//kirjan/kirjoittaja”).InnerText = ’jones’
$xdoc.catalog.book.author = ’smith’

Yleästi sinulla saattaa olla olemassa oleva XML-tiedosto, jossa haluat muuttaa yhtä tai useampaa solmun arvoa. Haluat luultavasti lukea tiedoston, muuttaa tietoja ja tallentaa tiedoston takaisin samalla nimellä. Olet nähnyt kaksi ensimmäistä vaihetta; kolmas vaihe tehdään XmlDocumentin Save-metodilla. Kun nämä kaikki yhdistetään, saadaan siis tämä peruskoodi:

Tämä koodi toimii hienosti – paitsi että useimmiten se näyttää epäonnistuneen! Tämä yksinkertainen koodinpätkä havainnollistaa näennäisesti vähäpätöisen mutta tärkeän PowerShell-käsitteen; tietämättömyys tästä on johtanut moniin blogikirjoituksiin, joissa väitetään, että kyseessä on PowerShellin virhe. Ongelma on se, että työhakemistosi ja PowerShell-sijaintisi eivät ole sama asia. Yllä oleva koodi lukee tiedoston hienosti, se muuttaa tietoja hienosti, mutta se ei välttämättä tallenna uutta tiedostoa sinne, minne odotat sen tallentuvan. Get-Content, joka on PowerShell-cmdlet, näkee tiedostopolun suhteessa PowerShell-sijaintiin. XmlDocument.Save-metodi puolestaan näkee tiedostopolun suhteessa PowerShell-prosessin työhakemistoon, koska kyseinen metodikutsu on PowerShellin ulkopuolella. Jos et ole suorittanut Set-Locationia (tai sen alias cd:tä) nykyisessä PowerShell-istunnossa, molemmat osoittavat samaan hakemistoon. Voit varmistaa tämän suorittamalla nämä kaksi lauseketta:

1
2

Get-Location # näyttää PowerShellin sijainnin
::CurrentDirectory # näyttää työhakemiston

Turvallisinta on siis käyttää absoluuttisia polkuja, jotta tämä ongelma voidaan välttää kokonaan. Katso lisätietoja Alex Angelopoulosin artikkelista Why the PowerShell Working Directory and the PowerShell Location Aren’t One in the Same.

XML-tietojen lisääminen

Uusien solmujen lisääminen XML-dokumenttiin vaatii vain hieman enemmän työtä kuin olemassa olevan solmun arvon muuttaminen. Yksi lähestymistapa, josta pidän, on Tobias Weltnerin blogikirjoituksesta Write, Add and Change XML Data (XML-tietojen kirjoittaminen, lisääminen ja muuttaminen): ota olemassa oleva solmu sen tyyppinen, jonka haluat luoda, tee kopio kyseisestä solmusta ja muuta kopiota uusilla tiedoillasi, ja lopuksi lisää kopioitu solmu XML:ään alkuperäisen solmun sisarukseksi. Soveltamalla tätä kirjaluettelon esimerkkiin tämä koodinpätkä luo uuden kirjasolmun ja lisää sen kokoelman loppuun:

Jos haluat lisätä uuden kirjan eri paikkaan, vaikkapa 3. kirjan jälkeen, käytä InsertAfteria AppendChildin sijaan:

1
$xdoc.catalog.InsertAfter($book,$xdoc.catalog.book)

(Metodin InsertAfter nimi pettää sen, että se ei vain lisää solmuja, vaan se voi myös siirtää solmuja! Metodi tarkistaa, onko lisättävä solmu jo dokumentissa. Jos näin on, se siirtää sen määrittelemäänne uuteen paikkaan. Näin ollen, kun haluat kopioida solmuja, sinun on aloitettava Clone-metodilla, kuten edellä on kuvattu.)

Lisätietoa XML-tietojen käsittelystä .NET-menetelmillä löydät kohdasta XML-tietojen käsitteleminen DOM-mallin avulla MSDN:stä.

XML:n käyttö objektien sarjallistamiseen

PowerShell tarjoaa helpon tavan objektien pysyvään säilytykseen käyttämällä Export-Clixml-menetelmää, jolla voidaan sarjallistaa mikä tahansa objekti ja säilyttää se XML-tiedostossa, ja Import-Clixml-menetelmää, jolla voidaan palauttaa objekti XML:stä. Toisin kuin useimmissa muissa sarjallistamistekniikoissa, XML:n avulla objektin eheys säilyy: kun objekti palautetaan XML:stä, kaikki ominaisuudet ovat oikein tyypitettyjä, samoin kuin itse emo-objekti, joten kaikki alkuperäisen objektin metodit ovat käytettävissä myös palautetussa objektissa. Jos haluat käyttää Export-Clixml:ää, lähetä siihen mikä tahansa objektikokoelma ja määritä kohdetiedosto. Tässä on yksinkertainen esimerkki, jossa näytetään, että Get-ChildItem-olion, FileSystemInfo-olioiden kokoelman, tuloste regeneroidaan:

Vastaa

Sähköpostiosoitettasi ei julkaista.