Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing XML nodes in PowerShell

Tags:

powershell

xml

I have two XML files (File1.xml, File2.xml). File2.xml is a subset of File1.xml.

File1.xml has nodes like so:

<parentnode>
    <item id="GUID1">
         <Text>Some Text</Text> 
    </item>
    <item id="GUID2">
        <Text>Here’s some more text</Text> 
    </item>
</parentnode>

File2.xml has:

<parentnode>
    <item id="GUID1">
         <Text>Some Replacement Text</Text> 
    </item>
</parentnode>

I want to take the item with GUIDx in File1.xml, and replace it with the item with GUIDx from File2.xml. Essentially, I want to take the replacement text in File2.xml and insert it into the corresponding item node in File1.xml

How do I do this in PowerShell?

like image 541
Keith Avatar asked Mar 18 '11 22:03

Keith


People also ask

How do I update the specific node of the XML file using PowerShell?

To update the specific XML node using PowerShell, we first need to select that node with the attribute with SelectSingleNode() method. We have below the XML file from the link stored in SampleXml. XML on C:\Temp location. The above commands will load the XML file and select node with attribute value 'bk102'.

How do I delete an XML node in PowerShell?

To delete the specific XML node from the PowerShell, we can use the RemoveChild() method of the XML. For example, We have a sample XML file from Microsoft. We have saved the above file into C:\Temp\SampleXml.

How do I replace a string in PowerShell?

One of the easiest ways to replace strings in PowerShell replace command method as shown below. The replace() method has two arguments; the string to find and the string to replace the found text with. As you can see below, PowerShell is finding the string hello and replacing that string with the string hi .


1 Answers

Suppose I have first xml in variable $edited and the second in $new. Then you can change value in item with id GUID1 via

$edited.parentnode.item | 
   ? { $_.id -eq 'guid1' } | 
   % { $_.Text = $new.parentnode.item.Text }
# and save the file
$edited.Save('d:\File1.xml')
# see the changes
gc d:\File1.xml

In case you have more items to replace, you could use nested pipelines:

$edited = [xml]@"
<parentnode>
    <item id="GUID1"><Text>Some Text</Text></item>
    <item id="GUID2"><Text>Here’s some more text</Text></item>
    <item id="GUID3"><Text>Here’s some more text</Text></item>
    <item id="GUID10"><Text>Here’s some more text</Text></item>
</parentnode>
"@
$new = [xml] @"
<parentnode>
    <item id="GUID1"><Text>new Guid1</Text></item>
    <item id="GUID2"><Text>new Guid2</Text></item>
    <item id="GUID3"><Text>new Guid3</Text></item>
    <item id="GUID4"><Text>new Guid4</Text></item>
    <item id="GUID5"><Text>new Guid5</Text></item>
</parentnode>
"@
$new.parentnode.item | 
    % { ,($_.id,$_.Text)} | 
    % { $id,$text = $_; 
        $edited.parentnode.item | 
           ? { $_.id -eq $id } | 
           % { $_.Text = $text }
    }

or foreach cycle which is more readable here:

foreach($i in $new.parentnode.item) { 
    $edited.parentnode.item | 
           ? { $_.id -eq $i.Id } | 
           % { $_.Text = $i.Text }
    }
like image 120
stej Avatar answered Sep 29 '22 16:09

stej