{"id":1181,"date":"2014-06-13T00:01:00","date_gmt":"2014-06-13T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/06\/13\/calling-xmldocument-methods-in-powershell\/"},"modified":"2022-06-21T14:03:50","modified_gmt":"2022-06-21T21:03:50","slug":"calling-xmldocument-methods-in-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/calling-xmldocument-methods-in-powershell\/","title":{"rendered":"Calling XMLDocument Methods in PowerShell"},"content":{"rendered":"<p><strong>Summary<\/strong>: Microsoft Scripting Guy, Ed Wilson, talks about calling <strong>XMLDocument<\/strong> methods in Windows PowerShell.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Today is Friday the 13<sup>th<\/sup>. Cool. Luckily, I do not have to go anywhere tonight around midnight, by the light of a full moon. But I am going to use Windows PowerShell methods to slice and dice some XML. Luckily, this is a very neat technique, and it will not leave any wayward bits of data laying around. Besides, I am listening to <a href=\"https:\/\/www.youtube.com\/watch?v=SpTS4O1nFyc&#038;feature=youtu.be\" target=\"_blank\" rel=\"noopener\">Scripting Cmdlet Style<\/a>, and that should scare off anything that is non-PowerShell related.<\/p>\n<p><strong>\u00a0 \u00a0 Note\u00a0<\/strong> This is the fifth in a series of posts about working with XML. You might also enjoy reading:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/creating-an-xml-document-for-admins\/\" target=\"_blank\" rel=\"noopener\">Creating an XML Document for Admins<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/exploring-xml-document-by-using-the-xml-type-accelerator\/\" target=\"_blank\" rel=\"noopener\">Exploring XML Document by Using the [XML] Type Accelerator<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/using-powershell-to-explore-structure-of-an-xml-document\/\" target=\"_blank\" rel=\"noopener\">Using PowerShell to Explore Structure of XML Document<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/calling-xml-document-properties-from-within-powershell\/\" target=\"_blank\" rel=\"noopener\">Calling XML Document Properties from Within PowerShell<\/a><\/li>\n<\/ul>\n<p>Although Windows PowerShell makes it easy to navigate XML documents, at times (because of the size of the files, the numbers of nodes, or some other non-PowerShell related element), one may want to drop down to the .NET Framework to do some work.<\/p>\n<p>To make things a bit more interesting today, I decided to use an XML document from MSDN called <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/ms762271(v=vs.85).aspx\" target=\"_blank\" rel=\"noopener\">Sample XML File (books.xml)<\/a>. All one needs to do to use it is to copy the code from the MSDN page, paste it into a plain Notepad text file, and rename the file <strong>Books.xml<\/strong>. After I have done that, I open it in XML Notepad for fun. This is what I find:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-01.png\" alt=\"Image of menu\" title=\"Image of menu\" \/><\/a><\/p>\n<p>One of my favorite <strong>XMLDocument<\/strong> methods is the <strong>SelectNodes<\/strong> method. It will accept an XPATH path, which is simply a specially formatted string. The easiest XPATH query to use is <strong>\u201c*\u201d<\/strong>, which means, &#8220;Dude, show me everything.&#8221;<\/p>\n<p>In the following example, I first read in the XML by using <strong>Get-Content<\/strong> and the [XML] type accelerator. I then use the <strong>ChildNodes<\/strong> property and the <strong>SelectNodes<\/strong> method.<\/p>\n<p style=\"margin-left:30px\">\n  [xml]$xmldocument = Get-Content C:\\fso\\books.xml\n<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.ChildNodes.selectNodes(&#8220;*&#8221;)\n<\/p>\n<p>The commands and the associated output from the commands is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Because I see that my query with the wildcard character (<strong>\u201c*\u201d<\/strong>) worked as I thought it would, I decide to get brave and return only the titles. I do this by using the forward slash ( <strong>\/ **) symbol as the separator, and I simply call the **Title<\/strong> node that I saw in the output from my first query. The query is shown here:<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.ChildNodes.selectNodes(&#8220;*\/title&#8221;)\n<\/p>\n<p>The following image shows the query and the associated output:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-03.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-03.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>I can also pick up the <strong>Genre<\/strong> of the books, as shown here:<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.ChildNodes.selectNodes(&#8220;*\/genre&#8221;)\n<\/p>\n<p>The command and associated output are shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-04.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-04.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The list of genres looks cool, but I really only want to know what genres are represented\u2014that is, I want a unique list. Because this is Windows PowerShell, I can easily find this information in a couple of ways. The way I like to do this is to use <strong>Select-Object<\/strong> and specify the <strong>\u2013Unique<\/strong> switch:<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.ChildNodes.selectNodes(&#8220;*\/genre&#8221;) | select &#8216;#text&#8217; \u2013Unique\n<\/p>\n<p>The output is nice, and it lets me know only the genres that are unique in the list:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-05.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-05.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Maybe I want to know the value of all of my books, and how many books I actually have. This is easy to do with Windows PowerShell, XML, and XPath. Here is the command I use:<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.ChildNodes.SelectNodes(&#8220;*\/price&#8221;) | measure &#8216;#text&#8217; \u2013Sum\n<\/p>\n<p>Here is the command and the output from the command:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-06.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-06.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Now I want to add one of my books to the Books.xml file. To do this, I will first clone one of the book nodes, as shown here:<\/p>\n<p style=\"margin-left:30px\">\n  $copy = $xmldocument.catalog.book[0].Clone()\n<\/p>\n<p>Now, I simply assign new values for each of the properties. This appears here:<\/p>\n<p style=\"margin-left:30px\">\n  $copy.id = &#8216;bk113&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $copy.author = &#8216;Wilson, Ed&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $copy.title = &#8216;Windows PowerShell Best Practices&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $copy.price = &#8216;59.99&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $copy.publish_date = &#8216;2014-01-25&#8217;\n<\/p>\n<p style=\"margin-left:30px\">\n  $copy.description = &#8216;Automate system administration using Windows PowerShell best practices\u2019\n<\/p>\n<p>Now, I want to add the new node to the XML. I do this by calling the appendchild method and passing the $copy. This appears here:<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.catalog.appendchild($copy)\n<\/p>\n<p>I can now check the child nodes to ensure that it is added:<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.ChildNodes.childnodes\n<\/p>\n<p>Now I write the <strong>InnerXML<\/strong> to a text file with the XML extension:<\/p>\n<p style=\"margin-left:30px\">\n  $xmldocument.InnerXml >>c:\\fso\\modified.xml\n<\/p>\n<p>I can now open it in XML Notepad to see if it worked properly. Here is my output:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-07.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-6-13-14-07.png\" alt=\"Image of menu\" title=\"Image of menu\" \/><\/a><\/p>\n<p>That is all there is to using XML methods. Join me tomorrow for the Weekend Scripter when I will talk about non-PowerShell books for Windows PowerShell people.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\" rel=\"noopener\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\" rel=\"noopener\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\" rel=\"noopener\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\" rel=\"noopener\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about calling XMLDocument methods in Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, is here. Today is Friday the 13th. Cool. Luckily, I do not have to go anywhere tonight around midnight, by the light of a full moon. But I am going to use Windows PowerShell methods to [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,45,165],"class_list":["post-1181","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell","tag-xml"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about calling XMLDocument methods in Windows PowerShell. Microsoft Scripting Guy, Ed Wilson, is here. Today is Friday the 13th. Cool. Luckily, I do not have to go anywhere tonight around midnight, by the light of a full moon. But I am going to use Windows PowerShell methods to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=1181"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1181\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=1181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=1181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=1181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}