Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I rename an XML node using PowerShell?

Tags:

powershell

xml

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?

like image 718
craveness Avatar asked Jun 15 '11 00:06

craveness


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 you call XML in PowerShell?

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.

Can PowerShell parse XML?

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.


2 Answers

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>
like image 167
codepoke Avatar answered Sep 20 '22 20:09

codepoke


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.

like image 43
jsuddsjr Avatar answered Sep 19 '22 20:09

jsuddsjr