- 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: