I'm trying to rename an XML node using PowerShell. For example:
<configuration>
<desktops>
<name>PC001</name>
<domain>CORP</domain>
</desktops>
<laptops>
<name>PC002</name>
<domain>CORP</domain>
</laptops>
</configuration>
I want to rename the first <name>
tags to <PC1name>
(and </PC1name>
respectively). Here's what I have, so far:
$InputFile = "NetworkConfigs.xml"
$xml = [xml](get-content $InputFile)
$root = $xml.get_DocumentElement();
#replace the node
$root.desktops.name.?
$xml.Save($InputFile)
I don't know how to replace the <name>
tag with something else. Tips?
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'.
One way to read an XML document in PowerShell is to typecast a variable to the type [xml]. To create this variable, we can use the Get-Content cmdlet to read all of the text in an XML document. To typecast the output of Get-Content we can simply prepend the text [xml] before the variable.
Another way to use PowerShell to parse XML is to convert that XML to objects. The easiest way to do this is with the [xml] type accelerator. By prefixing the variable names with [xml] , PowerShell converts the original plain text XML into objects you can then work with.
Bottom line, an XML node's name is immutable. Reference msdn.
Here's a quick example of creating a new node with the required data. Hope it helps.
$InputText = @"
<configuration>
<desktops>
<name>PC001</name>
<domain>CORP</domain>
</desktops>
<laptops>
<name>PC002</name>
<domain>CORP</domain>
</laptops>
</configuration>
"@
$xml = [xml]($inputText)
$desktopsNode = [System.Xml.XmlElement]$xml.configuration.desktops
$nameNode = $desktopsNode.SelectSingleNode('name')
$pcNameNode = $xml.CreateElement('PC1Name')
$pcNameNode.InnerText = $nameNode.InnerText
[void]$desktopsNode.AppendChild($pcNameNode)
[void]$desktopsNode.RemoveChild($nameNode)
$xml.OuterXML
Output:
<configuration><desktops><domain>CORP</domain><PC1Name>PC001</PC1Name></desktops><laptops><name>PC002</n
ame><domain>CORP</domain></laptops></configuration>
Renaming nodes in XML is more complicated than you might expect. It's especially bad if the node is a root node, or parent with a complex hierarchy of child nodes. Most "rename" methods I've seen will clone the children and append them to the new node. This process is made a little easier if your API also includes a ReplaceChild method. (I can provide details if you need them.)
An alternative method that I have used (especially if the XML can be represented as a string) is to replace the text in the XML before converting it to XmlDocument.
$InputText = @"
<configuration>
<desktops>
<name>PC001</name>
<domain>CORP</domain>
</desktops>
<laptops>
<name>PC002</name>
<domain>CORP</domain>
</laptops>
</configuration>
"@
$regex = [regex]'(</?)name>'
$ModifiedText = $regex.Replace($InputText,"`$1PC1Name>",2)
$xml = [xml]$ModifiedText
Note that the replace statement finds and fixes the first 2 occurrences of the match--the opening and closing tag of the first element only. Remove the number to find and replace all occurrences in the string. Note also that the regular expression captures the opening tag characters, so that they can be inserted into the string match as $1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With