Reputation: 29
I need to Compare new names with name in XML file if name doesn't match then I would like to remove that actor from XML file, if the name doesn't existed then I would like to add it in.
$file = [xml]@'
<?xml version="1.0"?>
<data>
<title>Name</title>
<date>2019 Jan 01</date>
<actor>
<name>Actor Name 1</name>
<type>Actor</type>
<thumb>image.jpg</thumb>
</actor>
<actor>
<name>Actor Name 2</name>
<type>Actor</type>
<thumb>image.jpg</thumb>
</actor>
<genre>genre1</genre>
<genre>genre2</genre>
</data>
'@
I try below code but it doesn't work
$file = New-Object System.Xml.XmlDocument
$file.Load($file_path)
$file_data=$file.DocumentElement
$oldarray = $file_data.actor
$newarray=@(
"Actor 3",
"Actor Name 1"
)
Compare-Object -IncludeEqual -ReferenceObject $oldArray -DifferenceObject $newarray | Where-Object {
$w=$_.InputObject
if($_.SideIndicator -eq "=>"){
$a = $file_data.appendChild($file.CreateElement("actor"))
$a.AppendChild($file.CreateElement("name")).InnerText=$w.Trim()
$a.AppendChild($file.CreateElement("type")).InnerText="Actor"
}
if($_.SideIndicator -eq "<="){
$file_data.SelectSingleNode("//actor[text()='$w']") | foreach {[void]$_.parentnode.removechild($_)}
}
}
Upvotes: 0
Views: 153
Reputation: 174690
Start by removing <actor>
nodes where the <name>
is not in the list of new names:
$file = New-Object System.Xml.XmlDocument
$file.Load($file_path)
$file_data=$file.DocumentElement
$newNames = @(
"Actor 3"
"Actor Name 1"
)
# Use XPath to select all <name> nodes nested under an <actor> node
$existingNameNodes = $file.SelectNodes('//actor/name')
# Filter against the list of new names
$removableNameNodes = $existingNameNodes |Where-Object InnerText -notin $newNames
$removableNameNodes |ForEach-Object {
# Resolve parent <actor> node
$actor = $_.ParentNode
# Remove <actor> from its own parent
$actor.ParentNode.RemoveChild($actor) |Out-Null
}
Now we just need to add the ones not already in the list:
$existingNameNodes = $file.SelectNodes('//actor/name')
# Filter the new list against the existing names
$namesToAdd = $newNames |Where-Object { $_ -notin $existingNameNodes.InnerText }
foreach($name in $namesToAdd){
# Create new <actor> and <name> nodes
$newActorNode = $file.CreateElement('actor')
$newActorName = $file.CreateElement('name')
$newActorName.InnerText = $name
# Nest new <name> under new <actor>, nest <actor> under <data>
$file.data.AppendChild(
$newActor.AppendChild(
$newActorName
)
) |Out-Null
}
Upvotes: 1