Pregunta

Estoy escribiendo un script de PowerShell para manipular algunos Windows Installer XML (WiX). Estoy usando las nuevas API XML en .NET 3.5 para hacer esto, ya que me parece que es una API más fácil de trabajar que el DOM. El fragmento siguiente secuencia de comandos se niega a trabajar rotundamente:

[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

El script debe salida de cada etiqueta en una línea separada. Voy a conseguir que haga algo más interesante una vez que este error ha sido resuelto; -)

El documento XML es un archivo de localización estándar 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>

$ strings $ no es nulo (He probado de forma explícita), y si el huésped escribo $ wxl, puedo ver que el documento se ha cargado. $ Tuberías cadenas en Get-Member devuelve un error que indica que "Ningún objeto se ha especificado para obtener miembros" y escribir en host $ strings no hace nada. También he intentado $ wxl.Descendants ( "WixLocalization") con los mismos resultados. Cosas como $ wxl.Root y $ wxl.Nodes funcionan como se esperaba. Depuración con PowerShell ISE, veo que $ strings se ha establecido a IEnumerator, en lugar de la esperada IEnumerable . Prueba de la IEnumerator con una sola MoveNext y luego un actual indica que "Current =", presumiblemente $ nula.

Lo extraño es que la misma técnica trabajó en un guión previo. El mismo código, pero con diferentes nombres de variables y literales de cadena. Y después de haber intentado depurar simplemente que el guión también (para verificar el comportamiento), parece que es ahora también se muestra el mismo comportamiento.

¿Fue útil?

Solución

Este problema me ha intrigado, así que lo hice algunas búsquedas alrededor. Después de mucho andar por ahí en PowerShell y buscar en la web me encontré con su solución.

El crédito va a Jamie Thomson para el código real. http://dougfinke.com/blog/ index.php / 2007/08/07 / usando-xmllinq-en-powershell /

La pieza que falta es manejar el espacio de nombres en el archivo XML. Aquí está el código que debería funcionar para usted:

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

Otros consejos

Sé que dijo que no preferimos trabajar con el DOM, pero ¿hay alguna razón por la que esto no funciona para usted?

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

Esto da salida:

PS> $ test.WixLocalization.String

Id #text
- -----
0 Publicidad recurso publicado
1 La asignación de espacio de registro

Foreach'ing sobre eso no debería ser demasiado difícil en ese punto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top