7

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?

1 Answer 1

5

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 }
    }
Sign up to request clarification or add additional context in comments.

3 Comments

When I attempt to load my two xml files and run your code I get the following error: "Property 'Text' cannot be found on this object; make sure it exists and is settable." Here is the code I'm running: $edited = Get-Content file2.xml $new = Get-Content file1.xml $new.parent.item | % { ,($_.id,$_.Text)} | % { $id,$text = $_; $edited.parent.item | ? { $_.id -eq $id } | % { $_.Text = $text } }
You need to convert the text to xml when loading the files: $edited = [xml] (Get-Content file2.xml); $new = [xml] (Get-Content file1.xml)
Ah..yes. Thx! That was the trick. Not sure how I missed the [xml]. Thanks much, stej. Your code worked like a charm.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.