代码之家  ›  专栏  ›  技术社区  ›  alastairs

为什么XDocument.subjects()在PowerShell ISE中返回IEnumerator?

  •  1
  • alastairs  · 技术社区  · 17 年前

    我正在编写一个PowerShell脚本来操作一些Windows Installer XML(WiX)。我正在使用.NET3.5中新的XMLAPI来实现这一点,因为我发现它比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
    

    输出每个<字符串>标记在单独的行上。一旦这个bug被解决,我将让它做一些更有趣的事情;-)

    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(我已经显式地测试了它),如果我编写主机$wxl,我可以看到文档已经加载。将$strings管道传输到Get成员中会返回一个错误,指出“没有为Get成员指定对象”,而写入主机$strings不会执行任何操作。我还尝试了$wxl.subjects(“WixLocalization”),得到了同样的结果。像$wxl.Root和$wxl.Nodes这样的东西按预期工作。在调试PowerShell ISE时,我看到$strings已设置为IEnumerator,而不是预期的IEnumerable<XElement>。使用单个MoveNext和电流测试IEnumerator表明“Current=”,大概是$null。

    奇怪的是,同样的技术在以前的脚本中也起了作用。代码完全相同,但变量名和字符串文字不同。刚刚试过调试该脚本(以验证其行为),现在它似乎也显示了相同的行为。

    2 回复  |  直到 17 年前
        1
  •  5
  •   JasonMArcher TWE    17 年前

    这个问题引起了我的兴趣,所以我四处寻找。在PowerShell中进行了大量的混乱和网络搜索之后,我找到了您的解决方案。

    真正的代码归功于杰米·汤姆森。 http://dougfinke.com/blog/index.php/2007/08/07/using-xmllinq-in-powershell/

    [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
    }
    
        2
  •  1
  •   James Pogran    17 年前

    我知道您说过您不喜欢使用DOM,但是有什么原因导致这对您不起作用吗?

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

    这将产生:

    PS>$test.WixLocalization.String

    Id#文本
    -- -----
    0广告发布资源

    在那一点上,讨论这个问题应该不会太难。

    推荐文章