Powershell - foreach循环过早退出?

时间:2017-04-30 15:03:05

标签: powershell

原谅我,但我对Powershell很新。我有一个问题,理解为什么我的代码突然退出foreach循环,一旦代码找到一个名为“bk103”的书。我期待foreach循环遍历for循环12次,因为xml文件中有12本书。为什么要提前退出?

谢谢!

Set-Location 'C:\PowershellPractice\'                                                                        #'

[int]$index = 0

[string] $xmlFilePath=’C:\PowershellPractice\books.xml’

[xml] $xmlContent = [xml] (Get-Content -Path $xmlFilePath)

$newSubNode = $xmlContent.CreateElement("security")
$newSubNode.SetAttribute("Mode", "transport")

$collection = $xmlContent.catalog.ChildNodes

Write-Host "Collection has " $collection.Count " elements in it!"

foreach ($item in $collection){
   Write-Host "In foreach, index is " $index
   if ($item.id -eq "bk103" -OR 
       $item.id -eq "bk105" -OR 
       $item.id -eq "bk108" -OR 
       $item.id -eq "bk109"){
         Write-Host "Found book called " $ $item.id
         $elementCopy = $xmlContent.catalog.book[$index].Clone()
         $elementCopy.AppendChild($newSubNode)
         $xmlContent.catalog.RemoveChild($item)
  $xmlContent.catalog.InsertBefore($elementCopy,$xmlContent.catalog.book[$index])

    }
$index++
}

$xmlContent.Save('C:\PowershellPractice\books-edited.xml')

1 个答案:

答案 0 :(得分:1)

正如评论中所提到的,当您正在迭代它时,您无法修改该集合。

由于您只需要自己修改集合中的元素,我建议您这样做(而不是克隆book节点并重新附加它):

foreach ($item in $collection){
    Write-Host "In foreach, index is " $index
    if ($item.id -eq "bk103" -OR 
        $item.id -eq "bk105" -OR 
        $item.id -eq "bk108" -OR 
        $item.id -eq "bk109"){
        # Add subnode to matching $item
        [void]$item.AppendChild($newSubNode)
    }
}

如果您发现自己处于无法修改元素的情况,请使用两个循环 - 一个用于查找有趣的元素,另一个用于通过迭代生成的子集来替换它们:

# collect matching results
$foundbooks = foreach ($item in $collection){
    Write-Host "In foreach, index is " $index
    if ($item.id -eq "bk103" -OR 
        $item.id -eq "bk105" -OR 
        $item.id -eq "bk108" -OR 
        $item.id -eq "bk109"){
        # return matching $item
        $item
    }
}

# now modify based on initial results
foreach($book in $foundbooks){
    Write-Host "Found book called " $ $book.id

    $elementCopy = $book.Clone()
    [void]$elementCopy.AppendChild($newSubNode)
    [void]$xmlContent.catalog.InsertBefore($elementCopy,$book)
    [void]$xmlContent.catalog.RemoveChild($book)
}