2017-05-29 143 views
1

我正在使用powershell做一些清理复古pi游戏列表,但我坚持使用XML的语法。 目标是删除特定文件扩展名类型的所有游戏条目。Powershell:在XML节点中搜索文件扩展名并删除父节点

清单的格式为这样:

<?xml version="1.0"?> 
<gameList> 
    <game id="" source=""> 
     <path>./2020 Super Baseball (USA).SMC</path> 
     <name>2020 Super Baseball</name> 
     <desc /> 
     <image>./boxart/2020 Super Baseball (USA).png</image> 
     <marquee>./wheel/2020 Super Baseball (USA).png</marquee> 
     <video>./snap/2020 Super Baseball (USA).mp4</video> 
     <releasedate /> 
     <developer /> 
     <publisher /> 
     <genre /> 
    </game> 
    <game id="" source=""> 
     <path>./2020 Super Baseball (USA).smc</path> 
     <name>2020 Super Baseball</name> 
     <desc /> 
     <image>./boxart/2020 Super Baseball (USA).png</image> 
     <marquee>./wheel/2020 Super Baseball (USA).png</marquee> 
     <video>./snap/2020 Super Baseball (USA).mp4</video> 
     <releasedate /> 
     <developer /> 
     <publisher /> 
     <genre /> 
    </game> 
</gameList> 

每场比赛既有.smc和.SMC项,我要删除的.SMC

到目前为止,我已经能够循环访问文件并删除路径中包含.SMC扩展名的每个游戏节点的内容。

# Load the existing document 
[xml]$xml = Get-Content "snes-gamelist.xml" 

#Iterate through each game node 
ForEach($Path in $xml.gamelist.game.path | Where-Object {$_ -like "*.SMC"}) 
{ 

$xml.SelectsingleNode("//path[.='"+$Path+"']") | % { 
$_.ParentNode.RemoveAll() } 

} 

#Output 
$xml.save("MOD-snes-gamelist.xml") 

问题是,实际的游戏节点仍然落后,我不知道如何完全删除它。

<?xml version="1.0"?> 
<gameList> 
    <game> 
    </game> 
    <game id="" source=""> 
     <path>./2020 Super Baseball (USA).smc</path> 
     <name>2020 Super Baseball</name> 
     <desc /> 
     <image>./boxart/2020 Super Baseball (USA).png</image> 
     <marquee>./wheel/2020 Super Baseball (USA).png</marquee> 
     <video>./snap/2020 Super Baseball (USA).mp4</video> 
     <releasedate /> 
     <developer /> 
     <publisher /> 
     <genre /> 
    </game> 
</gameList> 

在此先感谢。

回答

2

RemoveAll()从选定节点中删除所有内容。你想要做的是删除整个节点。

如果使用 foreach($node in $xml.gameList.game | Where-Object {$_.path -clike "*.SMC")}得到节点,你可以用$xml.gameList.RemoveChild($node)删除它。你

也应该使用-clike代替-like因为-like比较区分大小写,并且将匹配都.smc和.SMC。

+0

非常感谢J. Bergger。我实际上是在发布自己的解决方案,但是你的解决方案比我的解决方案要好得多。 –