【问题标题】:Strange behaviour -> .GetEnumerator() | .Reset() -> Looking for a way around奇怪的行为-> .GetEnumerator() | .Reset() -> 寻找解决方法
【发布时间】:2017-04-17 12:10:52
【问题描述】:

我正在 PowerShell 中处理一个简单的 XML 文件,由于我使用了 GetEnumerator() 方法,因此在使用我的脚本时会看到一些奇怪的事情。当我使用GetEnumerator() 方法将某些内容保存在对象中时,我只能使用该对象一次。之后我必须重新设置才能再次使用它。

我想摆脱这种行为。下面是一个示例脚本,它基本上展示了我如何在脚本中使用它。在函数的真实脚本中,我经常使用变量$ControlObject,并且每次都必须重置它。

我怎样才能以简单的方式防止这种情况发生?

$XMLTargetPath = Join-Path -Path $PSScriptRoot -ChildPath "XMLConfig.xml"

# Save XML in File for easy and fast reproduction
$XMLContentForFile = [xml]@"
<OuterNode>
  <BaseSettings>
    <Setting1>Blabla</Setting1>
  </BaseSettings>
  <DynamicSettings>
    <item>
        <Number>1</Number>
        <Name>January</Name>
    </item>
    <item>
        <Number>2</Number>
        <Name>February</Name>
    </item>
  </DynamicSettings>
</OuterNode>
"@
$XMLContentForFile.Save($XMLTargetPath)

function MyFunction {
    Param(
        [Parameter(Mandatory=$true, Position=0)]
        $ControlObject
    )

    $ControlObject     # Output the Object
    $ControlObject     # PROBLEM - I get no output ...

    # I need to make a reset to output the object again ...
    $ControlObject.Reset()
    $ControlObject
}

[xml]$xml = Get-Content -Path $XMLTargetPath

# Pass the XML-Node "Dynamic-Settings" into Function
MyFunction -ControlObject $xml.OuterNode.DynamicSettings.GetEnumerator()

【问题讨论】:

  • 无法重现。为我输出两个项目两次
  • @MathiasR.Jessen OP 期望输出出现三次:重置前两次,重置后一次。

标签: xml powershell enumerator


【解决方案1】:

我认为您误解了枚举器和 PowerShell 默认输出的工作方式。 PowerShell automagically appends | Out-Default 用于输出处理:

它调用引擎来获取提示,然后显示它并收集用户输入。然后它接受该输入,连接| Out-Default 并将其提交给引擎以供执行。 ... 是的,在幕后,通过控制台主机输入的每个命令都通过管道传输到 Out-Default

但是,管道会自动展开枚举器(否则它将无法显示枚举或可枚举集合的元素)。正因为如此,只是回显一个变量本质上与循环 enumerator 相同:

while ($ControlObject.MoveNext()) {
    $ControlObject.Current
}

在输出操作之后,枚举器位于枚举的末尾,因此您需要先将其移动到开头,然后才能再次枚举元素。这就是Reset() 所做的。

为什么管道不会自动重置枚举?我不知道,但可能不会产生无限循环。

底线:你不能一边吃蛋糕一边吃。需要展开枚举,以便显示元素,并且由于枚举不会自动重置,因此您需要自己执行此操作,然后才能再次枚举元素。

如果您只想要所选节点的嵌套元素,您可能应该使用ChildNodes 属性而不是枚举器。

MyFunction -ControlObject $xml.OuterNode.DynamicSettings.ChildNodes

【讨论】:

  • 我不能将枚举的内容保存在一个对象中以获得“正常”对象的行为吗?以及如何以一种简单的方式?
  • @Walhalla 当您不想要枚举器时,您干脆不使用枚举器怎么样? $xml.OuterNode.DynamicSettings.ChildNodes 是你真正想要的。
  • 我需要进一步测试它,但我认为“$xml.OuterNode.DynamicSettings.ChildNodes”是答案;-)
  • 如果您将此作为答案发布,也许带有“.ChildNotes”与“.GetEnumerator”的比较/描述,我会将其标记为答案!非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-16
  • 1970-01-01
  • 2016-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多