Redgate Hub

  • Accesarea datelor XML în PowerShell
    • Accesarea XML cu XPath.
    • Accesarea XML ca obiecte.
    • Compararea abordărilor XPath și Obiect
  • Modificarea sau crearea de date XML
    • Adăugarea de date XML
    • Utilizarea XML pentru serializarea obiectelor

Introducere

Ca orice limbaj de nivel înalt, the data se află în centrul PowerShell. În cazul PowerShell, aceasta se rezumă la convertirea datelor externe în obiecte PowerShell și invers. Acesta este al doilea dintr-o serie de articole care vă arată cum să importați aproape toate formatele de date comune pe care este posibil să le întâlniți și cum să exportați, de asemenea, în unele dintre ele. Primul articol din această serie, PowerShell Data Basics: File-Based Data (Date bazate pe fișiere), acoperă o varietate de formate de text, de la fișiere cu lățime fixă, cu lățime variabilă și ragged-right la CSV, liste de proprietăți, fișiere INI și date JSON, și se încheie cu tratarea importului și exportului în Excel. Aici ne concentrăm pe obținerea celor mai bune rezultate din XML.

Accesarea datelor XML în PowerShell

Există două tehnici încorporate pentru a lucra cu date XML în PowerShell; abordarea XPath și abordarea de notare a punctelor obiect. Vom descrie și compara aceste două abordări și le vom încerca pe câteva exemple XML. Pentru comoditate, toate exemplele de cod folosesc acest fișier XML de probă de la MSDN. Figura 1 arată o reprezentare a schemei care stă la baza fișierului într-un format concis (în special în comparație cu citirea fișierului XSD brut!), prin amabilitatea XML Schema Explorer din Visual Studio. Din figură, veți observa că fișierul XML este un catalog care conține o colecție de cărți. Fiecare carte are șapte caracteristici, dintre care șase sunt elemente copil și unul este un atribut copil.

Figura 1 Schema pentru exemplul de fișier XML de la Microsofto:p>

Pentru a încărca acest exemplu de fișier XML, puteți utiliza oricare dintre acestea:

dacă preferați să experimentați cu date XML imediate în loc să încărcați un fișier XML într-un XmlDocument, este simplu de făcut. Pur și simplu definiți XML-ul dvs. ca un șir de caractere și transformați-l în tipul XML, așa cum tocmai am făcut cu cmdlet-ul Get-Content pentru fișiere. Iată o porțiune din exemplul de fișier XML cu doar două cărți:

Accesarea XML cu XPath

Cu fișierul încărcat într-un obiect XmlDocument, puteți apoi să navigați în arborele XML cu XPath. Pentru a selecta un set de noduri folosiți metoda SelectNodes:

$xdoc.SelectNodes(„//autor”)

#text

Gambardella, Matthew

Ralls, Kim

Corets, Eva

Corets, Eva

Corets, Eva

Corets, Eva

Randall, Cynthia

Thurman, Paula

Knorr, Stefan

Kress, Peter

O’Brien, Tim

O’Brien, Tim

Galos, Mike

Sau utilizați SelectSingleNode pentru a returna doar un singur nod:

$xdoc.SelectSingleNode(„//book”)

id : bk102

autor : Ralls, Kim

titlu : Midnight Rain

gen : Fantezie

preț : 5.95

data publicării : 2000-12-16

descriere : O fostă arhitectă se luptă cu zombi corporatiști,

cu o vrăjitoare malefică și cu propria copilărie pentru a deveni regina

lumii.

Observați în primul exemplu că există duplicate. Să presupunem în schimb că doriți o listă a autorilor unici din catalog. V-ați putea gândi că ceva de genul …

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

…ar funcționa, dar, de fapt, returnează doar numele primului autor. Pentru a înțelege de ce a eșuat, ar trebui să înțelegeți mai multe despre structura documentelor XML. Primul exemplu a returnat, de fapt, o listă de noduri de text (adică nu o listă de text), iar filtrul unic operează pe această listă, căutând unicitatea tipului de element. Având în vedere că toate elementele din colecție sunt noduri de text și, prin urmare, toate sunt de același tip de element, toate nodurile de după primul sunt considerate, prin urmare, ca fiind duplicate. Rezultatul este că doar primul este returnat.

Ceea ce căutați cu adevărat este valoarea de șir de caractere a fiecărui nod de autor. De la nodul autor trebuie să accesați mai întâi nodul text al acestuia (primul și singurul său copil), apoi valoarea acelui nod text (linia A din exemplul următor). Alternativ, puteți utiliza o expresie puțin mai scurtă cu proprietatea InnerText (linia B). Încă o variantă utilizează cmdlet-ul Select-Xml, care evită apelarea unei metode și, astfel, este, într-un anumit sens, o abordare mai distinctă de PowerShell (linia C). Toate cele trei linii returnează același rezultat.

SelectNodes și SelectSingleNode împreună vă oferă o funcționalitate echivalentă cu Select-Xml. Ambele suportă namespace-uri, pe care nu le-am menționat încă. Cele două metode primesc ambele un XmlNamespaceManager ca al doilea parametru opțional, în timp ce cmdlet-ul Select-Xml primește un parametru opțional Namespace care specifică spațiile de nume într-un tabel hash.

SelectSingleNode returnează un XmlNode, iar SelectNodes returnează o listă XmlNodeList. Select-Xml, pe de altă parte, returnează un obiect SelectXmlInfo (sau o matrice a acestora), iar proprietatea Node oferă acces la nodul subiacent. Exemplul de mai sus ilustrează aceste diferențe.

Accesarea XML ca obiecte

Cu același obiect XmlDocument din ultima secțiune, PowerShell oferă, de asemenea, suport dinamic pentru obiecte pentru datele XML: Acest lucru vă permite să accesați datele XML ca obiecte PowerShell de primă clasă, neavând nevoie nici de selectorul XPath, nici de familiarizarea cu detaliile unor lucruri cum ar fi nodurile XML, valorile sau nodurile de text. În plus, obțineți instantaneu Intellisense dinamic al schemei XML atunci când încărcați datele XML! Figura 2 ilustrează acest lucru pentru PowerShell ISE, unde obțineți atât opțiuni de selecție, cât și completare de cuvinte, la fel ca în cazul token-urilor native PowerShell. Observați în special în expansiunea de jos că se caută ceea ce ați tastat oriunde în numele proprietății, nu doar începând de la primul caracter: Intellisense vă va găsi aici o proprietate de dată, indiferent dacă se numește published_date sau releaseDate sau date_of_publication. Rețineți că aveți la dispoziție funcția de completare a cuvintelor în PowerShell V2 sau V3, precum și în PowerShell ISE sau în consola PowerShell. Dar opțiunile de selecție sunt disponibile doar în PowerShell ISE în V3.

Figura 2 Intellisense automat la încărcarea unui document XML

Iată câteva exemple pentru a arăta că XML-ul este într-adevăr convertit automat în obiecte PowerShell:

$xdoc

xml catalog

– —

version=”1.0″ catalog

$xdoc.catalog

book

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

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

id autor titlu titlu gen preț data_publicării descriere

– — — — — — — —- —-

bk101 Gambardella, Matthew XML Developer’s Guide Computer 44.95 2000-10-01 O privire în profunzime …

bk102 Ralls, Kim Midnight Rain Fantasy 5.95 2000-12-16 Un fost arhitect …

bk103 Corets, Eva Maeve Ascendant Fantasy 5.95 2000-11-17 După prăbușirea …

bk104 Corets, Eva Oberon’s Legacy Fantasy 5.95 2000-11-17 După prăbușirea …

bk104 Corets, Eva Oberon’s Legacy Fantasy 5.95 2001-03-10 În post-apocalips…

bk105 Corets, Eva The Sundered Grail Fantasy 5.95 2001-09-10 Cele două fiice…

bk106 Randall, Cynthia Lover Birds Romance 4.95 2000-09-02 Când Carla întâlnește …

bk107 Thurman, Paula Splish Splash Romance 4.95 2000-09-02 Când Carla întâlnește …

bk107 Thurman, Paula Splish Splash Romance 4.95 2000-11-02 Un scafandru de mare adâncime …

bk108 Knorr, Stefan Creepy Crawlies Horror 4.95 2000-12-06 O antologie de h…

bk109 Kress, Peter Paradoxul pierdut Science Fiction 6.95 2000-11-02 După ce, din greșeală, un …

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

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

bk112 Galos, Mike Visual Studio 7: A Compr…

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

$xdoc.catalog.book

id : bk103

autor : Corets, Eva

titlu : Maeve Ascendant

gen : Fantezie

preț : 5.95

data publicării : 2000-11-17

descriere : După prăbușirea unei societăți de nanotehnologie

în Anglia, tinerii supraviețuitori pun bazele

unei noi societăți

$xdoc.catalog.book.author

Randall, Cynthia

$xdoc.catalog.book.id

bk106

Observați că toate nodurile XML din document sunt convertite în proprietăți PowerShell standard, indiferent dacă un nod are copii (de exemplu, catalog) sau este un nod frunză (de exemplu, preț), sau dacă un nod frunză este un element (de exemplu, autor) sau un atribut (de exemplu, id). În special (așa cum ilustrează ultimele două exemple de mai sus), valorile elementelor și valorile atributelor sunt tratate exact la fel cu notația standard „punct”.

Compararea abordărilor XPath și Object

Ce abordare este mai bună pentru a accesa datele XML? Tabelul 1 vă ajută să răspundeți la această întrebare. Abordarea obiect este de obicei mai concisă (de exemplu, linia 3), dar nu întotdeauna (linia 4). Cu toate acestea, XPath este mai expresiv, în sensul că vă permite să specificați anumiți selectori care nu sunt posibili cu notația obiect (linia 7). Cu toate acestea, capacitățile proprii ale PowerShell pot umple cu ușurință această lacună atunci când se utilizează notația obiect (linia 8).

Tabelul 1 Compararea abordărilor prin selectori XPath și obiect pentru accesul la XML.

Modificarea sau crearea de date XML

Dată o apreciere a selectorilor XML din secțiunile anterioare, modificarea unui document XML este destul de simplă, deoarece selectorii XML (fie XPath, fie obiect) sunt valori L, adică se poate scrie în ei, precum și citi din ei! Astfel, oricare dintre acestea va modifica autorul celei de-a 6-a cărți:

1
2

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

Destul de des, este posibil să aveți un fișier XML existent în care doriți să modificați una sau valorile unui nod. Probabil că ați dori să citiți fișierul, să modificați datele și să salvați din nou fișierul cu același nume. Ați văzut primii doi pași; al treilea pas se face cu metoda Save din XmlDocument. Punând toate acestea laolaltă, se obține acest cod de bază:

Acest cod rulează bine – cu excepția faptului că de cele mai multe ori va părea că a eșuat! Această bucată simplă de cod ilustrează o noțiune PowerShell aparent minoră, dar importantă; ignorarea acesteia a dus la multe postări pe bloguri care susțin că este un bug în PowerShell. Problema este că directorul dvs. de lucru și locația PowerShell nu sunt același lucru. Codul de mai sus citește fișierul foarte bine, modifică datele foarte bine, dar nu salvează neapărat noul fișier acolo unde vă așteptați să o facă. Get-Content, fiind un cmdlet PowerShell, vede o cale de fișier în raport cu locația PowerShell. Metoda XmlDocument.Save, pe de altă parte, vede o cale de fișier în raport cu directorul de lucru al procesului PowerShell, deoarece apelul acestei metode se află în afara PowerShell. Dacă nu ați executat Set-Location (sau aliasul său cd) în sesiunea PowerShell curentă, ambele trimit la același director. Pentru a confirma acest lucru, executați aceste două instrucțiuni:

1
2

Get-Location # afișează locația PowerShell
::CurrentDirectory # afișează directorul de lucru

Abordarea cea mai sigură, prin urmare, este de a utiliza căi absolute pentru a evita complet această problemă. Pentru mai multe informații, consultați articolul lui Alex Angelopoulos Why the PowerShell Working Directory and the PowerShell Location Aren’t One in the Same.

Adding XML Data

Adaugarea de noi noduri în documentul XML necesită doar puțin mai multă muncă decât modificarea valorii unui nod existent. O abordare care îmi place este cea de la intrarea de pe blogul lui Tobias Weltner Write, Add and Change XML Data: luați un nod existent de tipul pe care doriți să îl creați, faceți o copie a acelui nod și modificați copia cu noile date și, în final, inserați nodul copiat în XML-ul dvs. ca un frate al originalului. Aplicând acest lucru la exemplul nostru de catalog de cărți, această bucată de cod creează un nou nod de carte și îl adaugă la sfârșitul colecției:

Dacă doriți să adăugați noua carte într-o altă locație, de exemplu după a treia carte, utilizați InsertAfter în loc de AppendChild:

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

(Numele metodei InsertAfter ascunde faptul că aceasta nu doar adaugă noduri, ci poate și muta noduri! Metoda verifică dacă nodul pe care cereți să îl adăugați se află deja în document. Dacă da, îl mută în noua locație pe care o specificați. Astfel, atunci când doriți să copiați noduri, trebuie să începeți cu metoda Clone, așa cum este ilustrat mai sus.)

Pentru mai multe explorări privind manipularea datelor XML cu metodele .NET, consultați Processarea datelor XML utilizând modelul DOM pe MSDN.

Utilizarea XML pentru serializarea obiectelor

PowerShell oferă o modalitate ușoară de a persista obiectele prin utilizarea Export-Clixml pentru a serializa orice obiect și a-l stoca într-un fișier XML și Import-Clixml pentru a restaura obiectul din XML. Cu XML, spre deosebire de majoritatea celorlalte tehnici de serializare, integritatea obiectului este păstrată: la restaurarea unui obiect din XML toate proprietățile sunt tipizate corespunzător, la fel ca și obiectul părinte însuși, astfel încât toate metodele de pe obiectul original sunt disponibile și pe obiectul regenerat. Pentru a utiliza Export-Clixml, este suficient să direcționați orice colecție de obiecte către acesta și să specificați un fișier de destinație. Iată un exemplu simplu care arată că ieșirea din Get-ChildItem, o colecție de obiecte FileSystemInfo, este regenerată:

.

Lasă un răspuns

Adresa ta de email nu va fi publicată.