Question

J'écris un script PowerShell pour manipuler certains Windows Installer XML (WiX). J'utilise les nouvelles API XML dans .NET 3.5 pour ce faire, que je trouve une API plus facile à utiliser que les DOM. Le fragment de script suivant est platement refuse de travailler:

[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

Le script devrait sortie chaque balise sur une ligne distincte. Je vais chercher à faire quelque chose de plus intéressant que ce bug a été résolu; -)

Le document XML est un fichier de localisation norme 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>

chaînes de $ ne sont pas $ null (je l'ai testé explicitement), et si j'écris hôte WXL de $, je peux voir que le document a été chargé. Piping chaînes de $ dans Get-Member retourne une erreur indiquant que « Aucun objet n'a été spécifié pour obtenir-membre » et write-host des chaînes de $ ne fait rien. J'ai aussi essayé $ wxl.Descendants ( « WixLocalization ») avec les mêmes résultats. Des choses comme $ wxl.Root et wxl.Nodes $ fonctionnent comme prévu. Débogage avec PowerShell ISE, je vois que les chaînes $ a été mis à IEnumerator, plutôt que le IEnumerable attendu . Test du IEnumerator avec un seul MoveNext puis un courant indique que « Current = », probablement $ null.

La chose étrange est que la même technique a travaillé dans un script précédent. Le même code, mais avec des noms de variables et les littéraux de chaîne. Et juste après avoir essayé de débogage trop (pour vérifier le comportement) ce script, il semble qu'il est l'affichage maintenant le même comportement.

Était-ce utile?

La solution

Ce problème m'a intriguée, donc je fait quelques recherches autour. Après beaucoup de déconner dans PowerShell et recherche sur le Web, j'ai trouvé votre solution.

Le crédit va à Jamie Thomson pour le code réel. http://dougfinke.com/blog/ index.php / 2007/08/07 / utilisant-xmllinq en Powershell /

La pièce manquante est de gérer l'espace de noms dans le fichier XML. Voici le code qui devrait fonctionner pour vous:

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

Autres conseils

Je sais que vous avez dit que vous ne préférions travailler avec les DOM, mais est-il une raison pour laquelle cela ne fonctionne pas pour vous?

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

Sorties:

PS> $ test.WixLocalization.String

Id #text
- -----
0 Publicité ressource publiée
1 espace de registre Allouer

Foreach'ing sur cela ne devrait pas être trop difficile à ce moment-là.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top