2009-11-12 17 views
18

Ho il seguente codice XML:analizzare XML in PowerShell

<?xml version="1.0" encoding="UTF-8"?> 
<sections> 
    <section name="Options"> 
    <item key="HLVersionControlWebServiceURL" value="http://www.personec.no/webservices/HLVersionControl/HLVersionControl.asmx" /> 
    <item key="AltinnWebServiceURL" value="https://www.altinn.no/webservices/DataExchange.asmx" /> 
    <item key="WorkDir" value="F:\Altinn\Work\" /> 
    <item key="CatalogDir" value="F:\Altinn\Work\" /> 
    </section> 
    <section name="Users"> 
    <item key="1" value="Admin" name="Administrator" fNr="" password="" entsystype="1" entsysid="180967" entsyspassword="" lastLogin="20091111161516" allowra0500="1" allowrf1037="1" allowra01821="1" allowra01822="0" allowrf1015="1" altinnuserpassword="/qwHHYwYinE=" /> 
    </section> 
    <section name="SchemaTypes"> 
    <item key="RF1037" displayname="Terminoppgave" inputdir="F:\Altinn\Work\" validationschema=".\melding-669-8570.xsd" isSubForm="0" isSignable="0" /> 
    <item key="RA0500" displayname="SSB Lønnsstatistikk" inputdir="C:\Program Files (x86)\Personec\Altinn Monitor\Work\" validationschema=".\melding-868-7612.xsd" isSubForm="0" isSignable="0" /> 
    <item key="RA01821" displayname="SSB Fraværsstatistikk bedrift" inputdir="C:\Program Files (x86)\Personec\Altinn Monitor\Work\" validationschema=".\melding-862-6190.xsd" isSubForm="0" isSignable="0" /> 
    <item key="RF1015" displayname="Årsoppgave m/ LTO" inputdir="C:\Program Files (x86)\Personec\Altinn Monitor\Work\" validationschema=".\melding-210-7928.xsd" orid="210" orversion="7928" isSubForm="0" isSignable="1" /> 
    <item key="RF1015U" displayname="" inputdir="" validationschema=".\melding-1083-7930.xsd" orid="1083" orversion="7930" isSubForm="1" isSignable="1" /> 
    </section> 
</sections> 

e ho bisogno di modificare la voce WorkDir chiave in PowerShell. Quando si utilizza "regular" xml-read, arrivo alle sezioni in alto (opzioni, utenti e così via) ma non i nodi "item key" all'interno di ciascuno. Come posso modificare il valore di WorkDir in PowerShell? (Mi rendo conto che potrebbe utilizzare una stringa sporca sostituire ma preferirei farlo "correttamente"

+0

questo [post] [1] ha funzionato meglio per me [1]: http://stackoverflow.com/questions/1328490/update-configsource-of-xml-element-in -web-config-using-powershell-by-passing-in-p –

risposta

13

Questa versione utilizza un po 'più di PowerShell e gestisce il caso degli articoli mulitple con le chiavi Workdir:

$xml = [xml](Get-Content foo.xml) 
$xpath = "/sections/section/item[@key='WorkDir']" 
Microsoft.PowerShell.Utility\Select-Xml $xml -XPath $xpath | 
    Foreach {$_.Node.SetAttribute('value', $pwd)} 
$xml.Save("$pwd\bar.xml") 

nota, se avete la PowerShell Community Extensions installato è possibile utilizzare il cmdlet Format-Xml per formattare l'output e salvarlo tramite ad esempio out-File:

$xml | Format-Xml -AttributesOnNewLine | Out-File bar.xml -enc utf8 

OTOH $ xml.Save() è più facile, tranne che si deve ricordare che probabilmente non ha la corretta directory corrente se si dovesse indicare solo il nome del file. Ecco perché ho usato "$ pwd \ bar.xml" nel primo esempio. Questo non è un problema con i cmdlet di PowerShell come Out-File.

+0

Perfetto! Anche se il mio PowerShell con i moduli non riesce a trovare "Format-Xml" per qualsiasi motivo.Ho dovuto usare invece il salvataggio. –

+0

@RiverC, scusa. Format-Xml è un comando delle estensioni della comunità PowerShell - http://pscx.codeplex.com. Avrei dovuto dirlo. –

6

È possibile caricare il tuo XML in una classe LINQ XDocument da PowerShell in questo modo:.

[Reflection.Assembly]::LoadWithpartialName("System.Xml.Linq") | Out-Null 
$xDoc = [System.Xml.Linq.XDocument]::Parse($myXmlString) 

Da lì è possibile utilizzare il solito LINQ to XML metodi per sostituire l'attributo come in this example. Se si preferisce è possibile utilizzare la vecchia classe XmlDocument in modo simile.

+0

Grazie. Speravo di poterlo fare in modo nativo da PowerShell senza usare altre classi .Net. – Trondh

+0

La build di PowerShell nel supporto XML è effettivamente XmlDocument - dovrebbe quindi essere possibile "nativamente" in PowerShell. Sto giocando, è strano. – Murph

+1

Tenere presente che PowerShell non supporta la sintassi del metodo di estensione statica C# 3.0 in cui è possibile richiamare il metodo ext su un'istanza. E IIRC, PowerShell non supporta neanche invocando metodi generici. Quindi, se crei oggetti XLINQ, sei a posto, ma se tenti di utilizzare la funzionalità di query LINQ (System.Linq.Enumerable), sarà un esercizio inutile. –

10

si potrebbe provare questo

$xmlFile = "d:\sample.xml" 

[xml]$doc = Get-Content $xmlFile 
$node = $doc.SelectSingleNode("/sections/section/item[@key='WorkDir']") 
$node.Value = "New-Value" 
$doc.Save($xmlFile) 

Continuerai a utilizzare alcune classi .Net e una query XPath per selezionare il nodo.

+2

È possibile utilizzare il cmdlet Select-Xml in PowerShell 2.0 al posto della chiamata al metodo SelectSingleNode. –

+0

Select-Xml è disponibile in PowerShell 1.0, tuttavia ritengo che quanto sopra sia ancora il modo più semplice per accedere e modificare il valore di un attributo. –

+0

FYI, Select-Xml è * non * disponibile in PowerShell 1.0. Arriva con le estensioni della community PowerShell che è probabilmente il motivo per cui lo vedi in 1.0. –

-1
$invocation = (Get-Variable MyInvocation).Value 
$directorypath = Split-Path $invocation.MyCommand.Path 


[xml]$userfile = Get-Content $directorypath\MainSetting.xml 
$Value = $userfile.GetElementsByTagName("node") 

Foreach ($ValueName in $Value) 
{ 
    $FinalValue=$ValueName.InnerXML 
}