June 12th, 2014

Calling XML Document Properties from Within PowerShell

Doctor Scripto
Scripter

Summary: Microsoft Scripting Guy, Ed Wilson, talks about calling XML document properties from within Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. Craig Liebendorfer is back. No, he is not working on the Hey, Scripting Guy! Blog, but he is working on the Script Center as a whole. My old collaborator brings a lot to the table when it comes to bouncing ideas around, taking chances, and thinking outside the box. In fact, in our first recent meeting, we both came up with (about the same time) an idea for a new Script Center Home page. I think it looks really cool, let me know what you think.

By the way, each of the lines takes you to different places in the Script Center. We thought it was an appropriate way to navigate around the Script Center. Yep! The Windows PowerShell console. Here is an image of the new Home page:

Image of menu

   Note  This is the fourth in a series of posts about working with XML. You might also enjoy reading:

The first thing I do when I call XML document properties is read the XML file into a variable. Today I am going to call the variable XMLDocument to make the script easier to read. I use the [xml] type accelerator to cast the text into an XMLDocument object. The following image shows the document I am going to work with in XML Notepad:

Image of menu

When looking around at the properties that are available for working with XML documents, I like to use the MSDN reference for XMLDocument Class. I keep it open in Internet Explorer on one of my monitors so it will be available if I need it.

From looking at the document in XML Notepad, I can see that the root node is called Users, and that each child node is called User. Beneath that, I can find the UserName and the Address nodes. So how does this work in the Windows PowerShell console?

The first thing I do is read in the XML file, cast it to XMLDocument, and store it in a variable. This is shown here:

[xml]$xmldocument = Get-Content C:\fso\users.xml

I know the root node is called Users, and so I address it as shown here:

PS C:\> $xmldocument.Users

 

User

—-

{User, User, User, User…}

I can see that the child nodes are called User, User, User… Therefore, I can simply call this from here:

PS C:\> $xmldocument.Users.User

 

ID                            UserName                      Address

—                            ——–                      ——-

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

But, I can also call the ChildNodes property. It returns the same thing, as shown here:

PS C:\> $xmldocument.Users.ChildNodes

 

ID                            UserName                      Address

—                            ——–                      ——-

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

I can always use ChildNodes to get child nodes in an XML document. For example, if I did not know that Users was at the root of the XML document, I could have used ChildNodes there. This technique is shown here:

$xmldocument.ChildNodes

The command and the output are shown here:

Image of command output

I see from the previous output, that the child nodes are named User. So I can gain access to them by calling them directly, as shown here:

PS C:\> $xmldocument.ChildNodes.user

 

ID                            UserName                      Address

—                            ——–                      ——-

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

But I also see in the previous image that the root is Users, and then I have User. So I can go back, change my command, and access them by name. This is shown here:

PS C:\> $xmldocument.users.user

 

ID                            UserName                      Address

—                            ——–                      ——-

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

But, because I know these are child nodes, I can also go back to my original script, and simply tack on ChildNodes, as shown here:

PS C:\> $xmldocument.ChildNodes.childnodes

 

ID                            UserName                      Address

—                            ——–                      ——-

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

0                             UserName                      Address

What is cool about this approach is that even if I do not know what the nodes are called, I can still find the information. All three of these techniques and their associated output (which is the same in each case) are shown in the following image:

Image of command output

Whichever approach I decide to take, the technique is the same. I can address the first node by indexing into it. This is shown here:

PS C:\> $xmldocument.ChildNodes.childnodes[0]

 

ID                            UserName                      Address

—                            ——–                      ——-

0                             UserName                      Address

I can now find the UserName information:

PS C:\> $xmldocument.ChildNodes.childnodes[0].UserName

 

FirstName              LastName               #text                 Password

———              ——–               —–                 ——–

Bob                    Smith                  BobSmith              password

I use the same technique to get the Address information:

PS C:\> $xmldocument.ChildNodes.childnodes[0].Address

 

Street                 City                   State                 Zip

——                 —-                   —–                 —

123 main street        anytown                wa                    1234567

But what if I did not know the names? Once again, I can use the more generic approach. Here is the FirstChild from the first child node. I can see that it is the same as UserName.

PS C:\> $xmldocument.ChildNodes.childnodes[0].FirstChild

 

FirstName              LastName               #text                 Password

———              ——–               —–                 ——–

Bob                    Smith                  BobSmith              password

The LastChild gives me the address information. This is shown here:

PS C:\> $xmldocument.ChildNodes.childnodes[0].LastChild

 

Street                 City                   State                 Zip

——                 —-                   —–                 —

123 main street        anytown                wa                    1234567

I can take this technique further, and address specific nodes or properties:

PS C:\> $xmldocument.Users.User.username

 

FirstName              LastName               #text                 Password

———              ——–               —–                 ——–

Bob                    Smith                  BobSmith              password

Bob                    Smith                  BobSmith              password

Bob                    Smith                  BobSmith              password

Bob                    Smith                  BobSmith              password

Bob                    Smith                  BobSmith              password

 

PS C:\> $xmldocument.Users.User.username.LastName

Smith

Smith

Smith

Smith

Smith

That is all there is to using some of the XMLDocument properties. XML Week will continue tomorrow when I will talk about more cool stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Author

The "Scripting Guys" is a historical title passed from scripter to scripter. The current revision has morphed into our good friend Doctor Scripto who has been with us since the very beginning.

0 comments

Discussion are closed.