0

If I have the following xml:

<staff>
    <employee>
        <Name>Bob Smith</Name>
        <function>management</function>
        <age>39</age>
        <stuff>
            <data>Some Data</data>
        </stuff>
    </employee>
    <employee>
        <Name>Sam Jones</Name>
        <function>security</function>
        <age>24</age>
        <stuff>
            <data>Some Other Data</data>
        </stuff>
    </employee>
</staff>    

I can access this with:

$FilePath = "c:\test.xml"
$XmlFiles = @()
$Index = -1

$xdoc = new-object System.Xml.XmlDocument
$xdoc.load($FilePath)

$xdoc.SelectNodes("//employee")

This returns all the information. But for < stuff > it just says stuff, it doesn't expand it to show the content of the < data > field.

How can I get it to show everything for each employee, including the < data > field?

IGGt
  • 2,627
  • 10
  • 42
  • 63
  • Have a Go[ogle](http://stackoverflow.com/questions/3389541/how-to-iterate-the-irregularly-named-children-of-an-xml-xmlelement-in-powershell) at recursive call of ChildNodes – lloyd Aug 11 '15 at 04:39

1 Answers1

0

Traversing the Nodes has been answered in c# many times. This is just a Translation to Powershell. Following an Example in C#

$FilePath = "c:\test.xml"
$XmlFiles = @()
$Index = -1

$xdoc = new-object System.Xml.XmlDocument
$xdoc.load($FilePath)

$xdoc.SelectSingleNode("staff")


function TraverseNodes(
[System.Xml.XmlLinkedNode] $root #XmlNode 
)
{
    if ($root -is [System.Xml.XmlElement])
    {
        Write-Host($root.Name)
        if ($root.HasChildNodes)
        {
            TraverseNodes($root.FirstChild)
        }
        if ($root.NextSibling -ne $null)
        {
            TraverseNodes($root.NextSibling)
        }
    }
    elseif ($root -is [System.Xml.XmlText])
    {
        $text = $root.InnerText
        Write-Host $text 
    }
    elseif ($root -is [System.Xml.XmlComment])
    {
        $text = $root.InnerText
        Write-Host $text 
        if ($root.HasChildNodes)
        {
            TraverseNodes($root.FirstChild)
        }
        if ($root.NextSibling -ne $null)
        {
            TraverseNodes($root.NextSibling)
        }
    }
}

$xdoc.ChildNodes |%{TraverseNodes $_ }

Original solution by Josh Close

Community
  • 1
  • 1
lloyd
  • 1,683
  • 2
  • 19
  • 23
  • cheers, I like the idea, but it is giving the following error: `TraverseNodes : Cannot process argument transformation on parameter 'root'. Cannot convert the "System.Xml.XPathNodeList" valu e of type "System.Xml.XPathNodeList" to type "System.Xml.XmlLinkedNode".` – IGGt Aug 11 '15 at 08:09
  • Updated answer to use single parent node. otherwise use the [System.Xml.XPathNodeList] $root as the functions parameter . – lloyd Aug 11 '15 at 08:29
  • cheers. Unfortunately still an error. This time: `TraverseNodes : Cannot process argument transformation on parameter 'root'. Cannot convert the "System.Xml.XmlDocument" value of type "System.Xml.XmlDocument" to type "System.Xml.XmlLinkedNode".` The first one returns a table with (Name, function, age, stuff) (stuff not expanded). The second one returns a list of names only `{Bob Smith, Sam Jones, Mark Perkins} ` – IGGt Aug 11 '15 at 09:16
  • updated answer to solve the error. You will need to experiment for your exact needs. – lloyd Aug 12 '15 at 01:12