<?xml version="1.0"?>
<Root>
<Book>
<Name>Title1</Name>
<Name>Title2</Name>
<Name>Title3</Name>
<Name>Title3</Name>
<Name>Title3</Name>
</Book>
</Root>
我想从Book节点中删除一些选定的Name元素。我尝试了以下方法,但似乎没有效果。使用给定数组删除子节点的正确方法是什么(例如$delnode
)?
$delnode = 'Title1','Title2'
$xml.Root.Book | ? {$delnode -eq $_.Name} | % {$xml.Root.Book.RemoveChild($_)}
提前致谢。
答案 0 :(得分:0)
$delnode = @('Title1','Title2')
($xml.Root.Book.ChildNodes | ? {$delnode -eq $_.InnerText}) | % {
$xml.Root.Book.RemoveChild($_) | Out-Null
}
几点说明:
ChildNodes
。InnerText
属性。RemoveChild()
返回已删除的元素。由于您不希望此元素显示在您的输出中,因此对RemoveChild()
的调用会通过管道传递到Out-Null
。ChildNodes
)调用之前,请注意围绕?
和%
来电的括号。这些是必需的,因为您不想在当前正在迭代的集合上调用RemoveChild()
。答案 1 :(得分:0)
$delnode = 'Title1','Title2' $xml.Root.Book.ChildNodes | ? { $delnode -contains $_.'#text'} | % { $xml.Root.Book.RemoveChild($_) }
答案 2 :(得分:0)
当管道给我带来麻烦时,我的第一条规则就是停止使用管道,将代码重构为部分,并使用ISE来调试中间变量上的断点,而不仅仅是调试,而是发现每个对象具有哪些属性(如#text
或InnerChild
等)。
这与JamesQMurphy给出的答案非常类似,但也可能导致更容易理解,更改和/或调试的代码。
[xml]$xml = (Get-Content D:\test\t1.xml)
Write-Output "`nbefore..."
$xml.Root.Book | ft
$delnode = 'Title1','Title2'
$nodesToDelete = @()
foreach ($title in $delnode) {
$nodesToDelete += $xml.Root.Book.ChildNodes | ? {$_.InnerText -eq $title}
}
Write-Output "`nto delete..."
$nodesToDelete | ft
Write-Output "`ndeleting..."
$nodesToDelete | % {$xml.Root.Book.RemoveChild($_) | Out-Null}
Write-Output "`nafter..."
$xml.Root.Book | ft