Frage

Ich schreibe ein Powershell-Skript einige Windows Installer XML (WiX) zu manipulieren. Ich verwende den neuen XML-APIs in .NET 3.5, dies zu tun, wie ich es eine einfachere API arbeiten als mit dem DOM finden. Das folgende Skript Fragment weigert sich rundweg zu arbeiten:

[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

Das Skript sollte Ausgang jedes -Tag auf einer separaten Zeile. Ich werde ihm etwas Interessanteres zu tun, um zu erhalten, sobald dieser Fehler behoben worden ist; -)

Das XML-Dokument ist eine Standard-WiX Lokalisierungsdatei:

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

$ Strings ist nicht $ null (ich es explizit getestet habe), und wenn ich $ BxL write-host, kann ich sehen, dass das Dokument geladen wurde. Piping $ Strings in Get-Member gibt einen Fehler, der besagt, dass „kein Objekt angegeben wurde get-member“ und Write-Host-Strings $ tut nichts. Ich habe auch $ wxl.Descendants ( „WixLocalization“) mit dem gleichen Ergebnis ausprobiert. Dinge wie $ wxl.Root und arbeiten $ wxl.Nodes wie erwartet. Debuggen mit Powershell ISE, ich sehe, dass hat $ Strings IEnumerator, anstatt der erwarteten IEnumerable gesetzt worden . Testen des IEnumerator mit einem einzigen Movenext und zeigt dann ein Strom, die „Current =“ vermutlich $ null.

Die seltsame Sache ist, dass die gleiche Technik, die in einem frühen Skript gearbeitet. Der exakt gleiche Code, aber mit unterschiedlichen Variablennamen und Stringliterale. Und nur versucht zu haben, das Debuggen des Skripts zu (um das Verhalten zu überprüfen), es scheint, es ist jetzt auch das gleiche Verhalten zeigt.

War es hilfreich?

Lösung

Dieses Problem hat mich fasziniert, so habe ich einige Benutzer um. Nach viel in Powershell rumgespielt und das Suchen im Internet fand ich Ihre Lösung.

Kredit geht für den eigentlichen Code zu Jamie Thomson. http://dougfinke.com/blog/ index.php / 2007/08/07 / using-xmllinq-in-Powershell /

Das fehlende Stück ist das Namespace in der XML-Datei zu behandeln. Hier ist der Code, der für Sie funktionieren soll:

[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
}

Andere Tipps

Ich weiß, Sie sagen, Sie lieber nicht mit dem DOM zu arbeiten, aber gibt es keinen Grund, warum dies nicht für Sie arbeitet?

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

Diese Ausgänge:

PS> $ test.WixLocalization.String

Id #text
- -----
0 Advertising veröffentlichte Ressource
1 Zuweisen von Registrierungsspeicher

Foreach'ing über das sollte nicht allzu schwierig sein, an diesem Punkt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top