remove element from xml file

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