Hi everybody,
here are some fundamentals to handle XML Files with powershell.
The following commands uses these XML File
1 2 3 4 5 6 7 8 9 10 | < config description = "Config file for testing" > < system description = "Document Management" > < document authorFirstName = "Kirk" authorSurname = "Author1" date = "20130503 01:15:43" description = "Document Hammet" index = "3" >C:\temp\doc0001.txt</ document > < document authorFirstName = "Lars" authorSurname = "Author5" date = "20130503 10:05:42" description = "Document Ulrich" index = "4" >C:\temp\doc0002.txt</ document > < document authorFirstName = "Cliff" authorSurname = "Author5" date = "20130612 11:54:33" description = "Document Burton" index = "6" >C:\temp\doc0051.txt</ document > < document authorFirstName = "Jason" authorSurname = "Author2" date = "20130806 04:02:41" description = "Document Newsted" index = "1" >C:\temp\doc0041.txt</ document > < document authorFirstName = "Robert" authorSurname = "Smith" date = "20131202 07:12:03" description = "Document Trujillo" index = "2" >C:\temp\doc0012.txt</ document > < document authorFirstName = "James" authorSurname = "Smith" date = "20130211 09:05:59" description = "Document Hetfield" index = "5" >C:\temp\doc0003.txt</ document > </ system > </ config > |
Creating a XML File, create a document root, create subelements, add and set attributes, save the file
1 2 3 4 5 6 7 8 9 10 11 12 | # Create a new XML File with config root node [System.XML.XMLDocument] $oXMLDocument = New-Object System.XML.XMLDocument # New Node [System.XML.XMLElement] $oXMLRoot = $oXMLDocument .CreateElement( "config" ) # Append as child to an existing node $oXMLDocument .appendChild( $oXMLRoot ) # Add a Attribute $oXMLRoot .SetAttribute( "description" , "Config file for testing" ) [System.XML.XMLElement] $oXMLSystem = $oXMLRoot .appendChild( $oXMLDocument .CreateElement( "system" )) $oXMLSystem .SetAttribute( "description" , "Document Management" ) # Save File $oXMLDocument .Save( "c:\temp\config.xml" ) |
Loading an existing XML File, read an element, do some XPATH queries
1 2 3 4 5 6 7 8 9 10 11 | # Loading a XML File [[xml]] $oXMLDocument = Get-Content -Path "c:\temp\config.xml" # or $oXMLDocument = New-Object System.XML.XMLDocument $oXMLDocument .Load( "c:\temp\config.xml" ) # Accessing a node/attribute write-host $oXMLDocument .config.description # Get all documents from Author "Smith" $oDocsSmith = $oXMLDocument .selectNodes( "config/system/document[@authorSurname=""Smith""]" ) # Get all documents from Author "Smith" with date February 2013, XPATH Query relative to document root, http://msdn.microsoft.com/en-US/library/ms256086.aspx $oDocsSmithFeb13 = $oXMLDocument .selectNodes( "config/system/document[@authorSurname=""Smith"" and starts-with(@date,""201302"")]" ) |
Here are some examples
Get all Titles from a RSS Feed
1 2 3 4 5 | [System.Net.WebClient] $oWebClient = New-Object System.Net.WebClient # Get Proxy from Internet Explorer oWebClient.proxy= [System.Net.WebProxy] ::GetDefaultProxy() $oRSSFeed .rss.channel.item |foreach { write-host $_ .title} |
Copy a XML Node from one document to another
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # Get XML Document Object from String [[xml]] $oConfig2Merge = '<config description="Users"> <customers> <user surname="Campbell" firstname="Wayne">Wayne</user> <user surname="Garth" firstname="Algar">Garth</user> <user surname="Cheers" firstname="Phil">Phil</user> </customers> </config>' # Migrate the customers node to our config file defined at the top of the post # Get the target config Node $oXMLConfigTarget = $oXMLDocument .selectSingleNode( "config" ) # Get the Node which is to migrate $oXMLCustomers = $oConfig2Merge .config.customers # or $oXMLCustomers = $oConfig2Merge .selectSingleNode( "config/customers" ) # Import the Node with the ImportNode Function from System.XML.XMLDocument $oXMLConfigTarget .appendChild( $oXMLDocument .ImportNode( $oXMLCustomers , $true )) $oXMLDocument .Save( "c:\temp\config.xml" ) |
To be continued…
Michael
How to add inner text value to a node?
Hi Anonymous??
it’s simple
PS H:\> [ xml ] $oXML=”<test></test>”
PS H:\> $oXML
test
—-
PS H:\> $oXML.test=”This is the innerText”
PS H:\> $oXML
test
—-
This is the innerText
Michael
U can use sharts as well i.e.
[ xml ] $oXML=””
$oXML.test=”add some stuff”
I just had to do this: all my values are like this
“”
Here is the code, this blog was the final piece I needed.
Thanks,
$xdoc = (get-content “d:\SFA\SingleFileArchiveService.exe.config”)
$xdoc.configuration.userSettings.’SingleFileArchiveService.Properties.Settings’
$xyz = $xdoc.configuration.userSettings.’SingleFileArchiveService.Properties.Settings’.setting | Where-Object {$_.Name -eq ‘RecordingDelay’}
$xyz.value=”2000″
$xdoc.Save($path)
PS… Love the Metallica Reference. You forgot “Document Mustaine”
/me listening to Megadeth right now…
Hi Jeremy,
if I extend the document Megadeth are the next I add
Metal up your ass
Michael
hi all,
how to do all of this but without storing XML to a file ? only using variables ?
thanks
Hi Theo,
create your XML “on the fly” as descripted at the end of the post:
[xml]$oConfig2Merge='<config description=”Users”>
<customers>
<user surname=”Campbell” firstname=”Wayne”>Wayne</user>
<user surname=”Garth” firstname=”Algar”>Garth</user>
<user surname=”Cheers” firstname=”Phil”>Phil</user>
</customers>
</config>’
The variable $oConfig2Merge contains the XML document.
and do not call the Save() method?
Michael
You. Are. Awesome. I’ve been looking for this solution for 2 days. 20 minutes after finding it, got my conversion working. AWESOME! Thank you!