This is our test XML:
- <?xml version="1.0" encoding="utf-8"?>
- <configuration>
- <startup>
- <supportedRuntime version="4.0" />
- </startup>
- <appSettings>
- <add key="UseSuperpowers" value="false" />
- <add key="IgnoreKryptonite" value="true" />
- </appSettings>
- </configuration>
Load XML
- [xml]$configXml = Get-Content -Path C:\TestFile.xml
If file contains corrupted xml or no xml at all you will get exception.
This cast is very interesting fact, at first I thought that PS searches for constructor of given type which accepts argument of left expression. But XmlDocument has neither constructor nor static method (something like Load(string)) which accepts string. PowerShell magic.
This process is called Attribute Transformation. It allows to perform hidden transformation of types in freestyle way (like instantiate XmlDocument and invoke its method LoadXml(string) instead of type cast). You can start your own investigation from here: http://goo.gl/iZEGA.
Navigate XML
Another PS magic issue. As you can notice, we can use our xml variable like dynamic to access its attributes or nodes.- # Access node
- Write-Host $configXml.configuration.startup.supportedRuntime.OuterXml
- # Output: <supportedRuntime version="4.0" />
- # Access attribute
- Write-Host $configXml.configuration.startup.supportedRuntime.version
- # Output: 4.0
- # Get colletion of nodes
- $configXml.configuration.appSettings.add.Count
- # Output: 2
- # Iterate collection of nodes
- $configXml.configuration.appSettings.add | %{ Write-Host $_.key }
- # Output: UseSuperpowers IgnoreKryptonite
Navigate via XPath
You can use XPath to select nodes and attributes with Select-Xml cmdlet. It does not return elements itself but SelectXmlInfo instances. Use their Node property to get node itself:- # Query node
- $XPath = "/configuration/startup/supportedRuntime"
- $node = ( $configXml | Select-Xml -XPath $XPath ).Node
- Write-Host $node.OuterXml
- # Output: <supportedRuntime version="4.0" />
- # Query attribute with condition
- $XPath = "/configuration/appSettings/add[@key='IgnoreKryptonite']/@value"
- $node = ( $configXml | Select-Xml -XPath $XPath ).Node
- Write-Host $node.Value
- # Output: false
Edit XML
To edit XML you need to navigate to any element via one of approaches described and change its InnerXML or InnetText properties (in case of attribute you need to change Value property):
- # Change attribute 1
- $configXml.configuration.startup.supportedRuntime.version = "5.0"
- # Will change attribute: <supportedRuntime version="5.0" />
- # Change attribute 2
- $XPath = "/configuration/appSettings/add[@key='UseSuperpowers']/@value"
- $node = ( $configXml | Select-Xml -XPath $XPath ).Node
- $node.Value = "true"
- # Will change attribute: <add key="UseSuperpowers" value="true" />
- # Add XML
- $configXml.InnerXml += "<!-- End -->"
- # Will add this comment to the very end
Create XML
- # Append attribute
- $newAttribute = $configXml.CreateAttribute('levelOfAwesome')
- $newAttribute.Value = "Highest"
- $configXml.configuration.startup.supportedRuntime.Attributes.Append($newAttribute)
- # Insert comment before tag
- $newComment = $configXml.CreateComment('This section is all about supported runtime')
- $startupNode = $configXml.configuration.startup;
- $startupNode.InsertBefore($newComment, $startupNode.supportedRuntime)
- # Append node with attributes
- $newNode = $configXml.CreateElement('add')
- $newAttribute = $configXml.CreateAttribute('key')
- $newAttribute.Value = "wearUnderwearOverPants"
- $newNode.Attributes.Append($newAttribute)
- $newAttribute = $configXml.CreateAttribute('value')
- $newAttribute.Value = "true"
- $newNode.Attributes.Append($newAttribute)
- $configXml.configuration.appSettings.AppendChild($newNode)
Save XML
Use $configXml.Save($filePath) to save human readable XML, because other approaches (like Set-Content -Path $someFile -Value $configXml.InnerXml) will loose tabulation and formatting and save all XML in one line:- Set-Content -Path C:\test.xml $configXml.InnerText
- # Result:
- # <?xml version="1.0" encoding="utf-8"?><configuration><startup><!--This section is all about supported runtime--><supportedRuntime version="4.0" levelOfAwesome="Highest" /></startup><appSettings><add key="UseSuperpowers" value="false" /><add key="IgnoreKryptonite" value="true" /></appSettings></configuration>
- $configXml.Save('C:\test.xml')
- # Result:
- # <?xml version="1.0" encoding="utf-8"?>
- # <configuration>
- # <startup>
- # <supportedRuntime version="4.0" />
- # </startup>
- # <appSettings>
- # <add key="UseSuperpowers" value="false" />
- # <add key="IgnoreKryptonite" value="true" />
- # </appSettings>
- # </configuration>
No comments:
Post a Comment