Solved

Powershell and XML question

Posted on 2014-01-14
2
382 Views
Last Modified: 2014-01-15
Hi - Powershell newbie. I have the following XML sample. I need to iterate through it via powershell and run some powershell code at each level. I am able to reach any one of the items but have not been successfull in looping through each one. I could use a sample of how to do this. For this example - just printing the text of each element to the console would be fine so long as I can replace that code with the actual code I need to accomplish the goal.

Here is the sample file. There are some elements that are nested as shown.

<?xml version="1.0" encoding="utf-8"?>
<Locations>
  <!-- There can be multiple locations -->
  <Location>
      <Name>Location A</Name>

	<!-- There can be multiple Drawers per location -->	  
  <Drawers>
      <Drawer>
        <Name>Drawer 1</Name>
		<!-- There can be multiple Files per Drawer -->	
        <Files>
          <File>
            <Name>File 1</Name>
			<!-- There can be multiple Custom Variables anywhere -->
			<Attributes>	
				<Attribute>ID</Attribute>
				<Attribute>User Name</Attribute>
				<Attribute>Another Variable</Attribute>
			</Attributes>	
			<!-- There can be multiple Folders per File -->
			<!-- Folders can be nested -->				
            <Folder>
              <Name>Folder 1</Name>
			  <!-- There can be multiple Custom Variables anywhere -->	
				<Attribute>ID</Attribute>
				<Attribute>User Name</Attribute>
			  <!-- There can be multiple Documents per Folder -->	
              <Document>
                <Name>Document 1</Name>
				<!-- There can be multiple Custom Variables anywhere -->	
				<Attribute>ID</Attribute>
				<Attribute>User Name</Attribute>
              </Document>
              <Document>
                <Name>Document 2</Name>
              </Document>
              <Document>
                <Name>Document 2</Name>
              </Document>
              <Folder>
                <Name>Folder 1.1</Name>
				<Repeatable>True</Repeatable>
				<Attribute>ID</Attribute>
				<Attribute>User Name</Attribute>
                <Document>
                  <Name>Document 1.1</Name>
                </Document>
                <Document>
                  <Name>Document 1.2</Name>
                </Document>
                <Document>
                  <Name>Document 1.2</Name>
                </Document>
					<Folder>
						<Name>Folder 1.1.1</Name>
						<Document>
						  <Name>Document 1.1.1</Name>
						</Document>
						<Document>
						  <Name>Document 1.1.2</Name>
						</Document>
						<Document>
						  <Name>Document 1.1.2</Name>
						</Document>
					</Folder>
				</Folder>
            </Folder>
          </File>
		  <File>
            <Name>File 2</Name>
            <Folder>
              <Name>Folder 1</Name>
              <Document>
                <Name>Document 1</Name>
              </Document>
              <Document>
                <Name>Document 2</Name>
              </Document>
              <Document>
                <Name>Document 2</Name>
              </Document>
              <Folder>
                <Name>Folder 1.1</Name>
                <Document>
                  <Name>Document 1.1</Name>
                </Document>
                <Document>
                  <Name>Document 1.2</Name>
                </Document>
                <Document>
                  <Name>Document 1.2</Name>
                </Document>
				</Folder>
            </Folder>
          </File>
        </Files>        
      </Drawer>
	  <!-- The next drawer with similar files, folders and documents as the first. -->	
      <Drawer>
      </Drawer>
    </Drawers>
  </Location>
</Locations>

Open in new window

0
Comment
Question by:ckelsoe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 500 total points
ID: 39782369
Hi, have a look at this. I've put comments in to make clear where to add/change code, maybe overkill but anyway...

Let me know if you have any questions.
# settings

$xmlFile = ’sample.xml’

# functions

Function ProcessXmlDoc
{
Param ([xml] $xmlDoc)

    foreach ($locationNode in $xmlDoc.Locations.Location) {
        # put code that needs to be performed for every <Location> node here.
        Write-Host (“* Location Name={0}” -f $locationNode.Name)
        foreach ($drawerNode in $locationNode.Drawers.Drawer) {
            # additional code for <Drawer> nodes here
            Write-Host (“** Location Name={0}, Drawer Name={1}” -f $locationNode.Name,$drawerNode.Name)
            foreach ($fileNode in $drawerNode.Files.File) {
                # additional code for <File> nodes here
                Write-Host (“*** Location Name={0}, Drawer Name={1}, File Name={2}” -f $locationNode.Name,$drawerNode.Name,$fileNode.Name)
                RecurseFolders $fileNode
            }
        }
    }
}

Function RecurseFolders
{
Param ([system.xml.xmlelement] $folderNodeParam,[string] $FolderPath = "") # <File> node or <Folder> node, both can contain <Folder> nodes

    # construct "path" to current file/folder tree in the xml document
    if ($FolderPath -ne "") {
        $FolderPath = $FolderPath + "/" + $folderNodeParam.Name
    } else {
        $FolderPath = $folderNodeParam.Name
    }

    # additional code for <Folder> nodes here

    if ($folderNodeParam.Document) {
        # additional code for <Folder> nodes which contain <Document> nodes here
        foreach ($documentNode in $folderNodeParam.Document) {
            # additional code for <Document> nodes here
            Write-Host (“**** Document Name={0}, Folder Path={1}” -f $documentNode.Name,$FolderPath) # $folderNodeParam.Name
        }
    }
    if ($folderNodeParam.Folder) {
        # additional code for <Folder> nodes which contain <Folder> nodes here
        foreach ($folderNode in $folderNodeParam.Folder) {
            RecurseFolders $folderNode $FolderPath
        }
    }
}

#main code

ProcessXmlDoc (Get-Content -Path $xmlFile)

Open in new window

PS: I'm not overly experienced in PowerShell myself but thought it would be a nice experience to try solving it, got this far, saw no reply yet and decided to post as this should get you started at least.
0
 

Author Comment

by:ckelsoe
ID: 39783548
Hi Robert,

I am impressed! Thank you for the excellent example.

I have more to figure out but this code example is a great start. Thanks.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to prepare an HTML email signature template file containing dynamic placeholders for users' Azure AD data. Furthermore, it explains how to use this file to remotely set up a department-wide email signature policy in Office …
In previous parts of this Nano Server deployment series, we learned how to create, deploy and configure Nano Server as a Hyper-V host. In this part, we will look for a clustering option. We will create a Hyper-V cluster of 3 Nano Server host nodes w…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question