Hey, Scripting Guy!Le Olimpiadi sono alle porte (oltre a un po' di XML)
Gli Scripting Guy di Microsoft
Scarica il codice per questo articolo: HeyScriptingGuy2008_02,exe (151KB)
È naturale, ogni volta che si parla delle leggende del mondo dello sport, tornano in mente gli stessi nomi: Babe Ruth. Pelé. Muhammad Ali. Walter Payton. ScooterK e MrRat. Johnny-
Ah ah, divertente, ma... davvero non ne hai mai sentito parlare? Mai nessuna notizia delle imprese di ScooterK e MrRat? D'accordo, per i lettori che non si sono aggiornati sulle Olimpiadi invernali dello scripting (dal 15 febbraio al 3 marzo presso il TechNet Script Center; vedere il sito microsoft.com/technet/scriptcenter/funzone/games), ScooterK e MrRat sono vere e proprie leggende, concorrenti che hanno realizzato punteggio pieno in almeno una divisione delle Olimpiadi invernali dello scripting del 2007.
Questa è la parte davvero interessante: chi di noi può realisticamente aspirare a diventare una leggenda del calcio come Pelé? Probabilmente nessuno. Qualcuno dei lettori può immaginare di diventare campione del mondo dei pesi massimi di pugilato? Qualcuno degli Scripting Guy, in effetti, quanto a peso è davvero massimo, purtroppo però gli manca la parte più propriamente pugilistica. Ma tutti, proprio tutti, possono invece aspirare a diventare il prossimo ScooterK o il prossimo MrRat.
Nota: in teoria, qualcuno potrebbe anche diventare il prossimo Babe Ruth. Basta riuscire a mangiare 24 hot dog tra una partita e l'altra di un doppio incontro di baseball.
Non è tuttavia il caso di agitarsi; siamo qui per istruire tutti i lettori su come diventare il prossimo ScooterK o MrRat (e forse anche il prossimo Bizzy o H2Data). È sufficiente presentarsi allo Script Center e partecipare alle Olimpiadi dello scripting. Il 15 febbraio pubblicheremo 10 diversi eventi (10 sfide di script) e sfideremo i partecipanti a completarne solo alcuni o tutti. I concorrenti devono scrivere uno script che risolve il problema e inviarlo via posta elettronica agli Scripting Guy (le istruzioni complete sono disponibili alla home page delle Olimpiadi dello scripting). Lo script inviato verrà testato e, se funziona, il concorrente guadagnerà dei punti. Per diventare una leggenda del mondo dello sport, basta completare in modo corretto tutti e 10 gli eventi. O almeno del mondo dello sport dello scripting, che è quasi la stessa cosa.
Le Olimpiadi dello scripting (dal 15 febbraio al 3 marzo) promettono di essere divertenti e pieni di sfide. Ciò che più conta, le Olimpiadi dello scripting sono aperte a tutti. Gli utenti che non hanno ancora accumulato una lunga esperienza nel campo degli script di amministrazione del sistema possono partecipare alla divisione per principianti; sono previsti tornei separati per i principianti in VBScript, Windows PowerShellTM e (novità di quest'anno) Perl. La divisione per principianti sembra troppo facile? Allora è meglio cimentarsi nella divisione avanzata, che prevede allo stesso modo competizioni in VBScript, Windows PowerShell e Perl.
Le Olimpiadi (abbiamo già scritto che si terranno dal 15 febbraio al 3 marzo?) sono senza false modestie l'evento principale della stagione dello scripting che non si può mancare. È già possibile visitare la home page dello Script Center per ottenere suggerimenti e trucchi su come allenarsi per la competizione, prima di tornare il 15 febbraio quando si darà ufficialmente inizio alle Olimpiadi.
Dal 15 febbraio al 3 marzo. Se qualcuno non l'avesse ancora capito.
Come? È vero: Un nuovo numero di Hey, Scripting Guy! oltre all'annuncio delle Olimpiadi dello scripting forse induce fin troppa emozione per un mese solo. Tuttavia, per rendere felici i bravi ragazzi di TechNet Magazine (il nostro scopo principale nella vita, inutile ripeterlo), abbiamo deciso di rischiare e pubblicare un nuovo articolo comunque.
Esattamente un anno fa (è passato davvero tutto questo tempo?), abbiamo pubblicato un articolo in cui si spiegava come utilizzare uno script per leggere un file XML. Ciò che non si diceva in quell'articolo è come si utilizza uno script per creare, scrivere e modificare un file XML. Questo mese abbiamo deciso di riparare quel torto. Qualcuno desiderava proprio sapere come scrivere uno script in grado di creare un file XML? Basta chiedere. O meglio, chiedere e aspettare un annetto che gli Scripting Guy riescano a risolvere il problema. Lo script è descritto nella Figura 1. È vero, sembra complicato, ma spiegheremo come funziona l'intero script.
Figure 1 Creazione di un file XML
Set xmlDoc = _
CreateObject("Microsoft.XMLDOM")
Set objRoot = _
xmlDoc.createElement("ITChecklist")
xmlDoc.appendChild objRoot
Set objRecord = _
xmlDoc.createElement("ComputerAudit")
objRoot.appendChild objRecord
Set objName = _
xmlDoc.createElement("ComputerName")
objName.Text = "atl-ws-001"
objRecord.appendChild objName
Set objDate = _
xmlDoc.createElement("AuditDate")
objDate.Text = Date
objRecord.appendChild objDate
Set objIntro = _
xmlDoc.createProcessingInstruction _
("xml","version='1.0'")
xmlDoc.insertBefore _
objIntro,xmlDoc.childNodes(0)
xmlDoc.Save "C:\Scripts\Audits.xml"
Per iniziare, si crea un'istanza dell'oggetto Microsoft.XMLDOM. Come è facile immaginare, questo è l'oggetto che consente di lavorare con i file XML. Lo scopo consiste nel produrre un semplice file XML che somigli alla Figura 2.
Figura 2** Il nostro obiettivo: un semplice file XML **
Per creare questo file XML, è prima di tutto necessario creare il nodo principale (ITChecklist). Come si esegue questa operazione? Così:
Set objRoot = _
xmlDoc.createElement("ITChecklist")
xmlDoc.appendChild objRoot
Facile, vero? È sufficiente chiamare il metodo createElement, passando a createElement il nome da attribuire al nodo principale. Quindi si chiama il metodo appendChild, passando il riferimento all'oggetto al nuovo elemento (objRoot) come unico parametro del metodo. A questo punto, il nodo principale è pronto.
Ma un momento; c'è dell'altro. Si crea il nodo ComputerAudit, un nodo figlio del nodo ITChecklist che rappresenta le informazioni per un singolo computer. Come si può notare, il codice per creare il nodo è simile al codice utilizzato per il nodo principale:
Set objRecord = _
xmlDoc.createElement("ComputerAudit")
objRoot.appendChild objRecord
Una differenza esiste ed è questa: quando è stato creato il nodo principale, si è chiamato appendChild sullo stesso documento XML (vedere il riferimento all'oggetto xmlDoc). Per aggiungere un nodo figlio nuovo al nodo principale, si chiama appendChild sul nodo principale (objRoot) invece del documento XML. Basta questo.
È altrettanto facile aggiungere i nodi ComputerName e AuditDate come nodi figlio di ComputerAudit. A tal fine, si segue una procedura simile: si deve chiamare createElement per creare un nodo nuovo, quindi chiamare appendChild per aggiungere il nuovo nodo al file
(quiz rapido: dove si chiamerà appendChild da questo momento in poi? Sì, esatto: da objRecord, il nodo padre (ComputerAudit) appena creato).
Poiché, inoltre, i nodi ComputerName e AuditDate devono contenere valori, è importante specificare anche un valore per la proprietà Text di ciascuno di questi nodi subito prima di aggiungerli al documento.
Tutto apparirà più chiaro quando si analizzerà il codice che crea effettivamente il nodo ComputerName:
Set objName = _
xmlDoc.createElement("ComputerName")
objName.Text = "atl-ws-001"
objRecord.appendChild objName
Come è facile prevedere, il codice per la creazione di AuditDate è quasi identico. È necessario specificare un nome di nodo diverso quando si chiama createElement e assegnare un valore diverso alla proprietà Text.
Ragazzi, sta diventando tutto troppo semplice!
Una volta creati i nodi per il primo (e, in questo caso, unico) record, si esegue questo piccolo blocco di codice:
Set objIntro = _
xmlDoc.createProcessingInstruction _
("xml","version='1.0'")
xmlDoc.insertBefore _
objIntro,xmlDoc.childNodes(0)
Il codice si limita a inserire il tag <?xml version="1.0" ?> all'inizio del file, garantendo la corretta formattazione del documento XML.
A questo punto, non resta che chiamare il metodo Save e salvare il nuovo file come C: \Scripts\Audits.xml:
xmlDoc.Save "C:\Scripts\Audits.xml"
Ecco un documento XML nuovo di zecca.
Quanto descritto finora è molto utile: ora si è appreso come si crea un file XML nuovo utilizzando uno script. È probabile che non si passi la maggior parte del tempo a creare davvero file XML nuovi, ma che invece capiti spesso di dover aggiungere nuovi dati a un file esistente. Gli Scripting Guy sanno anche come eseguire questa operazione.
In origine avevamo deciso di non divulgare a tutti il segreto di come aggiungere dati a un file XML esistente. Poi la nostra natura di persone gentili e generose ha preso il sopravvento e abbiamo deciso di fare un patto con i lettori di TechNet Magazine: se tutti i lettori della rivista accettano di partecipare alle Olimpiadi invernali dello scripting del 2008, in cambio noi sveleremo come utilizzare uno script per aggiungere dati a un file XML. Allora intendi partecipare anche tu alle Olimpiadi dello scripting?
Stiamo aspettando che tu ci risponda, sì proprio tu di Rochester, MN, USA.
Ecco, bene così. Comunque fidati, alle Olimpiadi dello scripting c'è sempre da divertirsi. Vedrai.
Ciò che è giusto è giusto e un patto è un patto: ecco come utilizzare uno script per aggiungere dati a un file XML esistente. Basta esaminare la Figura 3.
Figure 3 Aggiunte a un file XML
Set xmlDoc = _
CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")
Set objRoot = xmlDoc.documentElement
Set objRecord = _
xmlDoc.createElement("ComputerAudit")
objRoot.appendChild objRecord
Set objFieldValue = _
xmlDoc.createElement("ComputerName")
objFieldValue.Text = "atl-ws-100"
objRecord.appendChild objFieldValue
Set objFieldValue = _
xmlDoc.createElement("AuditDate")
objFieldValue.Text = Date
objRecord.appendChild objFieldValue
xmlDoc.Save "C:\Scripts\Audits.xml"
Come si può vedere, lo script non è molto diverso dal precedente con cui si è creato il file XML. Si inizia creando un'istanza dell'oggetto Microsoft.XMLDOM, impostando la proprietà Async su False, in modo che il documento venga caricato in modo sincrono piuttosto che asincrono. Qual è la differenza? Bene, se si caricasse il documento in modo asincrono, lo script sarebbe libero di procedere anche con il documento non ancora completamente caricato. Inutile dire che si possono verificare dei problemi quando si tenta di eseguire un'attività su un documento che non esiste ancora. Il caricamento sincrono del file XML garantisce inoltre che il file verrà completamente caricato prima che lo script possa procedere.
Per quanto riguarda il caricamento completo, in effetti viene chiamato il metodo Load per aprire il file C: \Scripts\Audits.xml. Non appena il file è aperto, si utilizza questa riga di codice per creare un'istanza della classe documentElement, che ha l'effetto di stabilire un'associazione all'elemento principale del documento. In questo caso, ovviamente, si tratta del nodo ITChecklist:
Set objRoot = xmlDoc.documentElement
Da qui in poi il procedimento è piuttosto semplice e diretto. Si crea una nuova istanza del nodo ComputerAudit, utilizzando il metodo appendChild per aggiungere il nuovo nodo al file. Si creano quindi delle istanze nuove dei nodi ComputerName e AuditDate, specificando i valori appropriati (rispettivamente, atl-ws-100 e la data corrente) per ciascun nuovo nodo. Questi due elementi vengono inseriti nel nuovo nodo ComputerAudit appena creato, si chiama il metodo Save per salvare il file e si torna soddisfatti a lavorare sugli script per le imminenti Olimpiadi dello scripting.
Che, se non si fosse ancora capito, sono previste tra il 15 febbraio e il 3 marzo presso il TechNet Script Center.
Fin qui tutto bene. È possibile creare un nuovo file XML e aggiungere dei nuovi record a tale file. Molto interessante, ma ci sono altri segreti da svelare e script da scrivere; ad esempio, come si modificano i record esistenti nel file? Ecco almeno un modo per eseguire l'operazione, come illustrato nella Figura 4.
Figure 4 Modifica di un file XML
Set xmlDoc = _
CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")
Set colNodes=xmlDoc.selectNodes _
("/ITChecklist/ComputerAudit " & _
"[ComputerName = 'atl-ws-100']/AuditDate")
For Each objNode in colNodes
objNode.Text = Date
Next
xmlDoc.Save "C:\Scripts\Audits.xml"
La parte importante di questo script è la chiamata del metodo selectNodes, un metodo che determina quali record verranno restituiti dalla query. Come è possibile vedere, quando si chiama selectNodes è necessario prestare attenzione a specificare due criteri: nell'esempio si desiderano solo i record in cui l'attributo ComputerName è uguale a atl-ws-100 e la restituzione del solo attributo AuditDate.
Nota: non si capisce come funziona? Per schiarirsi le idee, basta leggere il primo articolo sui file XML (technetmagazine.com/issues/2007/02/HeyScriptingGuy); in quel documento la sintassi della query selectNodes è spiegata in maggior dettaglio.
Come è abituato a fare, selectNodes restituisce un insieme di tutti i record XML che soddisfano i criteri specificati. Ne consegue che, per aggiornare il valore dell'attributo AuditDate (il solo attributo richiesto), è sufficiente impostare un loop For Each e analizzare tutti gli elementi nella raccolta e, all'interno del loop, assegnare un nuovo valore ad AuditDate:
For Each objNode in colNodes
objNode.Text = Date
Next
Come? Qualcuno vorrebbe addirittura modificare più di un attributo per volta? Certo che è possibile. Ma non oggi, purtroppo; di certo se ne sentirà parlare negli articoli futuri.
Un'altra domanda può sorgere spontanea: come si aggiorna la data di controllo per tutti i computer nel file? È facile; si utilizza lo script della Figura 5.
Figure 5 Modifica della data di controllo
Set xmlDoc = _
CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")
Set colNodes=xmlDoc.selectNodes _
("/ITChecklist/ComputerAudit/AuditDate")
For Each objNode in colNodes
objNode.Text = Date
Next
xmlDoc.Save "C:\Scripts\Audits.xml"
Che differenza c'è tra questo script e lo script precedente di modifica del file XML? In questo script non è specificato che si desidera visualizzare solo i record in cui ComputerName è uguale ad atl-ws-100. Con l'omissione di questo criterio, si ottengono per impostazione predefinita tutti i record.
Prima di terminare l'articolo, è utile esaminare un ultimo script. Si supponga che, dopo aver giocato l'ultima mano di solitario, il caro vecchio atl-ws-100 sia passato a miglior vita nel grande cimitero dei computer nell'alto dei cieli.
Nota teologica: ma dove vanno i computer quando muoiono? A quanto sembra, vengono regalati a qualcuno degli Scripting Guy. Ad esempio, allo Scripting Guy che sta scrivendo questo articolo una volta è stato regalato un computer portatile perché "Fai un sacco di belle cose per Microsoft e un computer portatile ti servirà senz'altro". Il solo svantaggio di questa generosa offerta era l'impossibilità di accendere il computer, irrimediabilmente rotto. Ma anche una miracolosa accensione non avrebbe sortito grandi effetti, dal momento che mancava del tutto il disco rigido.
Per completare il grande ciclo della vita del silicio, è necessario eliminare atl-ws-100 dal file XML. Come si fa? Basta dare un'occhiata alla Figura 6.
Figure 6 Eliminazione dal file XML
Set xmlDoc = _
CreateObject("Microsoft.XMLDOM")
xmlDoc.Async = "False"
xmlDoc.Load("C:\Scripts\Audits.xml")
Set colNodes=xmlDoc.selectNodes _
("/ITChecklist/ComputerAudit " & _
"[ComputerName = 'atl-ws-100']")
For Each objNode in colNodes
xmlDoc.documentElement.removeChild _
(objNode)
Next
xmlDoc.Save "C:\Scripts\Audits.xml"
Anche questo somiglia a uno script precedente, in particolare quello utilizzato per modificare la proprietà di AuditDate. In verità qui le differenze sono due. Come è facile notare, non è stato specificato alcun valore della proprietà nella query selectNodes, quindi si ottiene l'intero record XML per atl-ws-100:
Set colNodes=xmlDoc.selectNodes _
("/ITChecklist/ComputerAudit " & _
"[ComputerName = 'atl-ws-100']")
Inoltre, all'interno del loop For Each, si chiama semplicemente il metodo removeChild per eliminare tutti i record in cui ComputerName è uguale ad atl-ws-100:
xmlDoc.documentElement.removeChild _
(objNode)
Ecco fatto! Addio, atl-ws-100; abbiamo avuto appena il tempo di conoscerci.
C'è ancora qualche redattore di TechNet Magazine che sta leggendo l'articolo di questo mese? Sono andati tutti via a tentare di risolvere il rompicapo di script mensile? Ottimo. Ora che nessuno legge, si può finalmente rivolgere il seguente invito al lettore: lascia perdere tutto ciò che stai facendo (anche leggere questa rivista) e passa subito allo Script Center per iniziare a prepararti per le Olimpiadi dello scripting. Dopotutto, TechNet Magazine resterà qui ancora per molto tempo, mentre le Olimpiadi dello scripting si tengono una sola volta l'anno e per un periodo limitato (in particolare, dal 15 febbraio al 3 marzo, tanto per essere informati). Non si può mancare!
Nota: a pensarci, abbiamo aspettato la fine dell'articolo prima di chiedere di smettere di leggere TechNet Magazine, vero? Che strano...
Il rompicapo di script del Dottor Scripto.
La sfida mensile che verifica non solo le tue capacità di risoluzione degli enigmi, ma anche le tue competenze di scripting.
Febbraio 2008: I simboli misteriosi
La tastiera di computer consente di scrivere ogni sorta di caratteri; molti di questi caratteri hanno addirittura una funzione specifica nei linguaggi VBScript o Windows PowerShell. Prova a riconoscere la funzione di ciascuno dei simboli all'interno di uno script. Il primo è tutto per te.
ANSWER:
Il rompicapo di script del Dottor Scripto.
Risposta: I simboli misteriosi, febbraio 2008
Gli Scripting Guy di Microsoft lavorano o, per meglio dire, sono stipendiati da Microsoft. Quando non si dedicano al baseball (o a varie altre attività) da giocatori, allenatori o semplici spettatori, gestiscono il TechNet Script Center. Consultare la pagina www.scriptingguys.com.
© 2008 Microsoft Corporation e CMP Media, LLC. Tutti i diritti riservati. È vietata la riproduzione completa o parziale senza autorizzazione.