لماذا XDocument.Descendants () عودة IEnumerator في بوويرشيل ISE؟
-
22-08-2019 - |
سؤال
وأنا أكتب نصي PowerShell لتلاعب بعض مثبت Windows XML (WIX). أنا باستخدام واجهات برمجة التطبيقات XML الجديدة في .NET Framework 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
والبرنامج النصي <م> يجب م> إخراج كل <سلسلة> العلامة في سطر منفصل. انا ذاهب الى الحصول عليها أن تفعل شيئا أكثر إثارة للاهتمام بمجرد أن تم حل هذا الخطأ؛ -)
وثيقة 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>
وسلاسل $ $ ليست فارغة (لقد اختبرت ذلك صراحة)، وإذا أنا أكتب في استضافة $ wxl، أستطيع أن أرى أن تم تحميل الوثيقة. سلاسل الأنابيب $ في الحصول على-عضو بإرجاع خطأ توضح أن "لم يتم تحديد الكائن للحصول عضوا" وسلاسل $ في استضافة إرسال لا يفعل شيئا. لقد حاولت ايضا $ wxl.Descendants ( "WixLocalization") مع نفس النتائج. أشياء مثل $ wxl.Root و$ wxl.Nodes تعمل كما هو متوقع. التصحيح مع بوويرشيل ISE، وأرى أن $ السلاسل تم تعيينها إلى IEnumerator، بدلا من IEnumerable المتوقع
والشيء الغريب هو أن التقنية نفسها عملت في السيناريو السابق. نفس الرمز المحدد، ولكن مع أسماء المتغيرات المختلفة والحرفية السلسلة. وبعد أن حاولت فقط أن التصحيح النصي جدا (للتحقق من السلوك)، ويبدو أنه الآن تظهر أيضا نفس السلوك.
المحلول
وهذه المشكلة مفتون لي، لذلك فعلت بعض البحث حول. بعد الكثير من العبث في بوويرشيل والبحث في الإنترنت وجدت الحل.
والائتمان يذهب إلى جيمي تومسون لرمز الفعلي. http://dougfinke.com/blog/ index.php / 2007/08/07 / باستخدام-xmllinq في وبوويرشيل /
وقطعة المفقود هو للتعامل مع مساحة في ملف 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.String
ورقم #text
- -----
0 الإعلان الموارد نشرت
1 تخصيص مساحة التسجيل
وForeach'ing على ذلك لا ينبغي أن يكون من الصعب جدا في هذه النقطة.