Я пишу сценарий PowerShell для управления некоторыми установщиками Windows Installer XML (WiX). Я использую новые XML-API в .NET 3.5 для этого, поскольку я считаю, что это более простой API для работы с DOM. Следующий фрагмент сценария категорически отказывается работать:Почему XDocument.Descendants() возвращает IEnumerator в PowerShell ISE?
[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
Сценарий должен выход каждого < Строка > тег на отдельной строке. Я собираюсь заставить его сделать что-то более интересное, когда эта ошибка была решена ;-)
документ 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>
$ строк не $ нулевой (I» ve явно протестировал его), и если я пишу-хост $ wxl, я вижу, что документ был загружен. Строка $ strings в Get-Member возвращает ошибку, в которой указано, что «No object не был указан для get-member», а строки $ str для записи-хозяина ничего не делают. Я также пробовал $ wxl.Descendants («WixLocalization») с теми же результатами. Такие вещи, как $ wxl.Root и $ wxl.Nodes работают должным образом. Отладка с помощью PowerShell ISE, я вижу, что $ strings был установлен в IEnumerator, а не ожидаемый IEnumerable <XElement>. Тестирование IEnumerator с помощью одного MoveNext, а затем Current указывает, что «Current =», предположительно, $ null.
Странно, что тот же метод работал в предыдущем сценарии. Точный же код, но с разными именами переменных и строковыми литералами. И просто попробовав отладку этого скрипта (чтобы проверить поведение), похоже, что теперь он также демонстрирует то же поведение.
Спасибо! Я, должно быть, прочитал это сообщение в блоге 100 раз, пока он искал эту статью, и каждый раз пропустил комментарии Джейми Томсона! Кажется, что в PowerShell существует переменная LINQ to XML, поскольку этого не происходит в C#. – alastairs