Domanda

Sto scrivendo uno script PowerShell per manipolare alcuni Windows Installer XML (WiX). Sto utilizzando le nuove API XML in .NET 3.5 per fare questo, come io trovo un'API più facile da lavorare rispetto al DOM. Il seguente frammento di script è categoricamente rifiuta di lavorare:

[System.Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null

# Basic idea: Iterate through en.wxl's l10ns, get string for each l10n, search all wxs files for that value.

pushd "C:\temp\installer_l10n"
$wxlFileName = "${pwd}\en.wxl"
$wxl = [System.Xml.Linq.XDocument]::Load($wxlFileName)
$strings = $wxl.Descendants("String")
$strings
$strings | foreach {
    $_
}
popd

Lo script dovrebbe uscita ogni tag su una riga separata. Ho intenzione di arrivare a fare qualcosa di più interessante una volta che questo bug è stato risolto; -)

Il documento XML è un file di localizzazione standard di WiX:

<?xml version="1.0" encoding="utf-8" ?>
<WixLocalization Culture="en-US" xmlns="http://schemas.microsoft.com/wix/2006/localization">
   <String Id="0">Advertising published resource</String>
   <String Id="1">Allocating registry space</String>
   ...
</WixLocalization>

$ stringhe non è $ null (ho provato in modo esplicito), e se scrivo-host $ WxL, posso vedere che il documento è stato caricato. Tubazioni $ stringhe in Get-Member restituisce un errore che indica che "Nessun oggetto è stato specificato per get-member" e Write-Host $ stringhe non fa nulla. Ho anche provato $ wxl.Descendants ( "WixLocalization") con gli stessi risultati. Cose come $ wxl.Root e $ wxl.Nodes funzionano come previsto. Debug con PowerShell ISE, vedo che $ stringhe è stato impostato su IEnumerator, piuttosto che l'IEnumerable previsto . Test del IEnumerator con un singolo MoveNext e poi una corrente indica che "Current =", presumibilmente $ null.

La cosa strana è che la stessa tecnica ha lavorato in uno script precedente. Lo stesso codice esatto, ma con diversi nomi di variabili e le stringhe letterali. E dopo aver appena provato il debug di script che troppo (per verificare il comportamento), a quanto pare è ora anche la visualizzazione lo stesso comportamento.

È stato utile?

Soluzione

Questo problema mi ha incuriosito, così ho fatto qualche ricerca in giro. Dopo un sacco di fare in giro in PowerShell e la ricerca sul web ho trovato la soluzione.

Il credito va a Jamie Thomson per il codice vero e proprio. http://dougfinke.com/blog/ index.php / 2007/08/07 / usando-xmllinq-in-PowerShell /

Il pezzo mancante è quello di gestire lo spazio dei nomi nel file XML. Ecco il codice che dovrebbe funzionare per voi:

[System.Reflection.Assembly]::LoadWithPartialName("System.Xml.Linq") | Out-Null
# Basic idea: Iterate through en.wxl's l10ns, get string for each l10n, search all wxs files for that value.

$wxlFileName = "${pwd}\en.wxl"
$wxl = [System.Xml.Linq.XDocument]::Load($wxlFileName)
$ns = [System.Xml.Linq.XNamespace]”http://schemas.microsoft.com/wix/2006/localization”
$strings = $wxl.Descendants($ns + "String")
foreach ($string in $strings) {
    $string
}

Altri suggerimenti

So che hai detto che non preferito lavorare con il DOM, ma c'è alcuna ragione per cui questo non funziona per voi?

[xml]$test = gc .\test.wml                                                                                        
$test                                                                                                             
$test.WixLocalization                                                                                             
$test.WixLocalization.String

Questa Uscite:

PS> $ test.WixLocalization.String

Id #text
- -----
0 Advertising risorsa pubblicata
1 Allocare lo spazio di registro

Foreach'ing oltre che non dovrebbe essere troppo difficile a quel punto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top