Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell,用于移动XML元素时vs Foreach_Xml_Powershell - Fatal编程技术网

Powershell,用于移动XML元素时vs Foreach

Powershell,用于移动XML元素时vs Foreach,xml,powershell,Xml,Powershell,我有一个将XML元素从一个位置移动到另一个位置的循环。对于For循环,它可以正常工作,但是对于Foreach循环,它将永远迭代。这只是XMLElement与foreach循环实现的不幸冲突,还是我缺少了更好的实践?我绝对不是System.Xml库的专家 演示脚本 输出 从快速实验来看,这确实是一个冲突,在试图在循环中修改迭代器的意义上。也就是说,您最初选择的是所有元素,包括目标中的元素。人们会认为这应该是无害的,但显然不是。要证明这一点,请将节点选择更改为: $files = $xmlDoc.S

我有一个将XML元素从一个位置移动到另一个位置的循环。对于For循环,它可以正常工作,但是对于Foreach循环,它将永远迭代。这只是XMLElement与foreach循环实现的不幸冲突,还是我缺少了更好的实践?我绝对不是System.Xml库的专家

演示脚本

输出


从快速实验来看,这确实是一个冲突,在试图在循环中修改迭代器的意义上。也就是说,您最初选择的是所有元素,包括目标中的元素。人们会认为这应该是无害的,但显然不是。要证明这一点,请将节点选择更改为:

$files = $xmlDoc.SelectNodes('//dir[@Id="source"]/file')
。。。其中,仅选择源中的那些文件节点。毕竟,不需要包括目标中的那些,因为它们已经在您想要的地方了。通过该更改,代码将按预期执行

下面是另一个可以使用的变体,返回到原始选择器。我只更改了标记为OctorOps的三行以获取节点,然后在单独的步骤中修改XML:

# Reset and try with a foreach loop
$xmlDoc = $xmlDocOriginalValue.Clone()
$files = $xmlDoc.SelectNodes('//file')
$destination = $xmlDoc.SelectSingleNode('//dir[@Id="destination"]')

Write-Host "`nForeach loop"
Write-Host "XML before: $($xmlDoc.OuterXml)"

$i = 0
$list = @()                                    ##############
foreach($file in $files) { $list += $file }    ##############
foreach($item in $list)                        ##############
{ 
    Write-Host ("Iteration "+$i + ", " + $file.OuterXml)
    $destination.AppendChild($item) | Out-Null 
    $i++
}
Write-Host "XML after: $($xmlDoc.OuterXml)"

啊哈,这就清楚了。我很惊讶上一行的查询被循环重新评估,这解释了无限循环。这不是我第一次看到PowerShell违反时间规则;SelectNodes返回的集合与上面创建的$list相比,必须具有某种特殊性。如果我感到好奇,我会审问它。谢谢是的,我很想知道你发现了什么!
$files = $xmlDoc.SelectNodes('//dir[@Id="source"]/file')
# Reset and try with a foreach loop
$xmlDoc = $xmlDocOriginalValue.Clone()
$files = $xmlDoc.SelectNodes('//file')
$destination = $xmlDoc.SelectSingleNode('//dir[@Id="destination"]')

Write-Host "`nForeach loop"
Write-Host "XML before: $($xmlDoc.OuterXml)"

$i = 0
$list = @()                                    ##############
foreach($file in $files) { $list += $file }    ##############
foreach($item in $list)                        ##############
{ 
    Write-Host ("Iteration "+$i + ", " + $file.OuterXml)
    $destination.AppendChild($item) | Out-Null 
    $i++
}
Write-Host "XML after: $($xmlDoc.OuterXml)"