Вопрос

Я пишу скрипт PowerShell для управления некоторым XML-файлом установщика Windows (WiX).Для этого я использую новые XML-API в .NET 3.5, поскольку нахожу, что с этим API работать проще, чем с DOM.Следующий фрагмент скрипта категорически отказывается работать:

[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

Сценарий следует выводите каждый <String> тег в отдельной строке.Я собираюсь заставить его сделать что-нибудь более интересное, как только эта ошибка будет устранена ;-)

XML-документ представляет собой стандартный файл локализации 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 не является $null (я явно протестировал это), и если я напишу-host $wxl, я увижу, что документ был загружен.Передача $strings в Get-Member возвращает ошибку, указывающую, что "Ни один объект не был указан для get-member", а write-host $strings ничего не делает.Я также попробовал $wxl.Descendants("WixLocalization") с теми же результатами.Такие вещи, как $wxl.Root и $wxl.Nodes, работают должным образом.Отлаживая с помощью PowerShell ISE, я вижу, что для $strings было установлено значение IEnumerator, а не ожидаемое значение IEnumerable<XElement>.Тестирование IEnumerator с помощью одного MoveNext, а затем Current указывает, что "Current = ", предположительно, $ null.

Самое странное, что та же техника сработала в предыдущем сценарии.Точно такой же код, но с разными именами переменных и строковыми литералами.И, только что попробовав отладить и этот скрипт (чтобы проверить поведение), похоже, что теперь он также отображает то же поведение.

Это было полезно?

Решение

Эта проблема заинтриговала меня, поэтому я немного поискал вокруг.После долгой возни с PowerShell и поиска в Интернете я нашел ваше решение.

За сам код нужно отдать должное Джейми Томсону.http://dougfinke.com/blog/index.php/2007/08/07/using-xmllinq-in-powershell/

Недостающая часть заключается в обработке пространства имен в XML-файле.Вот код, который должен работать у вас:

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

Другие советы

Я знаю, вы сказали, что предпочитаете не работать с DOM, но есть ли какая-то причина, по которой у вас это не работает?

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

Это выводит:

PS> $test.WixLocalization.Строка

Идентификатор #текст
-- -----
0 Рекламный опубликованный ресурс
1 Выделение места в реестре

На данный момент предварительное изучение этого не должно быть слишком сложным.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top