I have xml file which has a multiple element with same name
for example
<data>
<name></name>
<test>1</test>
<test>2</test>
<test>3</test>
</data>
I want to remove the element from xml if it matchs 3 for example.
I try following but it didnt work
$file_data.test| ? {$_ -eq 3 } | % {$file_data.test.RemoveChild($_)} | Out-Null
Basically, you want to use the Select-Xml cmdlet for this. Have a look at this article: Mastering Everyday XML Tasks in PowerShell. The “Finding Information in XML Files” and “Removing XML Information” sections should give you what you need.
You’re approach is looking for the value 3, instead of the test node with a value of 3. Find the node via XPath and then remove it. Here is one way using Grokkit’s suggestion, Select-XML
$xml = [xml]@'
<data>
<name></name>
<test>1</test>
<test>2</test>
<test>3</test>
</data>
'@
$xml | Select-Xml "//test[3]" | foreach {[void]$_.node.parentnode.removechild($_.node)}
And another using SelectSingleNode
$xml = [xml]@'
<data>
<name></name>
<test>1</test>
<test>2</test>
<test>3</test>
</data>
'@
$xml.SelectSingleNode("//test[3]") | foreach {[void]$_.parentnode.removechild($_)}
The output for both
PS C:\> $xml.data
name test
---- ----
{1, 2}
I try these way but it doesnt work on my file.
[xml]$file = ‘<?xml version=“1.0” encoding=“utf-8” standalone=“yes”?>
<movie>
<plot />
<outline />
<customrating>12</customrating>
<lockdata>true</lockdata>
<dateadded>2019-04-09 19:32:26</dateadded>
<title>Name of the file</title>
<rating>4.5</rating>
<year>2018</year>
<mpaa>15</mpaa>
<imdbid>13218067991122</imdbid>
<premiered>2018-11-19</premiered>
<releasedate>2018-11-19</releasedate>
<criticrating>5</criticrating>
<runtime>41</runtime>
<genre>genre</genre>
<genre>genre2</genre>
<genre>genre3</genre>
<genre>genre4</genre>
<genre>genre genre</genre>
<genre>genre 5</genre>
<genre>genre genre 2</genre>
<studio>Studio</studio>
<isuserfavorite>false</isuserfavorite>
<playcount>0</playcount>
<watched>false</watched>
<resume>
<position>0</position>
<total>2470.906</total>
</resume>
<actor>
<name>Actor 1</name>
<type>Actor</type>
</actor>
<actor>
<name>Actor 2</name>
<type>Actor</type>
</actor>
<id>13218067991122</id>
</movie>’;
$file_data = $file.DocumentElement
$newarray = @(
“genre”,
“genre2”,
“genre3”,
“genre4”,
“genre genre 3”,
“genre 5”,
“genre genre 2”
)
$oldarray = $file_data.genre
Compare-Object -IncludeEqual -ReferenceObject $oldArray -DifferenceObject $newarray | Where-Object -FilterScript {
#if($.SideIndicator -eq “=>”){Write-Host "New Object - " $.InputObject}
if($.SideIndicator -eq “<=”){
$w=$
.InputObject
$file_data.SelectSingleNode(“//genre[‘$w’]”) | foreach {[void]$.parentnode.removechild($)}
#Write-Host "Remove Object - " $_.InputObject
}
}
$file_data.genre
It does work in my tests, except it gets rid of the first entry. Your data has spaces in it so try this.
Compare-Object -IncludeEqual -ReferenceObject $oldArray -DifferenceObject $newarray | Where-Object -FilterScript {
#if($_.SideIndicator -eq "=>"){Write-Host "New Object - " $_.InputObject}
if($_.SideIndicator -eq "<="){
$w=$_.InputObject
$file_data.SelectSingleNode("//genre[text()='$w']") | foreach {[void]$_.parentnode.removechild($_)}
#Write-Host "Remove Object - $w"
}
}
$file_data.genre
[quote quote=246156]It does work in my tests, except it gets rid of the first entry. Your data has spaces in it so try this.
Compare-Object -IncludeEqual -ReferenceObject $oldArray -DifferenceObject $newarray | Where-Object -FilterScript {
#if($.SideIndicator -eq “=>”){Write-Host "New Object - " $.InputObject}
if($.SideIndicator -eq “<=”){
$w=$.InputObject
$file_data.SelectSingleNode(“//genre[text()=‘$w’]”) | foreach {[void]$.parentnode.removechild($)}
#Write-Host “Remove Object - $w”
}
}
$file_data.genre
[/quote]
This work. Thank you