Pergunta

Eu estou escrevendo um script PowerShell para manipular alguns Installer XML do Windows (WiX). Estou usando as novas APIs XML em .NET 3.5 para fazer isso, como eu encontrá-lo uma API mais fácil de trabalhar do que o DOM. O seguinte fragmento de script é simplesmente se recusar a trabalhar:

[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

O script deve saída de cada tag em uma linha separada. Eu estou indo para obtê-lo para fazer algo mais interessante, uma vez resolvido este bug; -)

O documento XML é um arquivo WiX localização padrão:

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

$ cordas não é $ null (Eu testei-lo explicitamente), e se eu escrever-host $ LxC, eu posso ver que o documento foi carregado. Tubulação $ strings em Get-Member retorna um erro informando que "Nenhum objeto foi especificado para get-member" e write-Host $ cordas não faz nada. Eu também tentei $ wxl.Descendants ( "WixLocalization"), com os mesmos resultados. Coisas como $ wxl.Root e trabalho $ wxl.Nodes como esperado. Depuração com o PowerShell ISE, vejo que $ cordas foi definido para IEnumerator, ao invés do IEnumerable esperado . Testando o IEnumerator com um único MoveNext e, em seguida, um atual indica que "= atuais", presumivelmente $ null.

O estranho é que a mesma técnica trabalhou em um script anterior. Exatamente o mesmo código, mas com diferentes nomes de variáveis ??e strings literais. E, tendo apenas tentei depurar o script também (para verificar o comportamento), parece que agora está também exibindo o mesmo comportamento.

Foi útil?

Solução

Este problema me intrigou, então eu fiz alguma pesquisa ao redor. Depois de muito andar em PowerShell e pesquisar na web eu encontrei a solução.

O crédito vai para Jamie Thomson para o código real. http://dougfinke.com/blog/ index.php / 2007/08/07 / utilizando-xmllinq-in-powershell /

A peça que falta é lidar com o namespace no arquivo XML. Aqui está o código que deve funcionar para você:

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

Outras dicas

Eu sei que você disse que não preferiu trabalhar com o DOM, mas há qualquer razão para que isso não funciona para você?

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

Esta saídas:

PS> $ test.WixLocalization.String

Id #text
- -----
0 Publicidade recurso publicado
1 a alocação de espaço de registro

Foreach'ing sobre isso não deve ser muito difícil nesse ponto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top