HiveBrain v1.2.0
Get Started
← Back to all entries
patternshellMinor

Chain nesting XML elements

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
nestingelementsxmlchain

Problem

I have a scenario where I need to chain nest XmlElements, and I got a working solution using a recursive function, but I can't help but feel that it can be made better.

Here's my code so far:

function AppendChild
{
    param
    (
        [string[]]$string,
        $obj,
        [System.Xml.XmlDocument]$XML
    )
    if ($string.Length -gt 0)
    {
        $child = $XML.CreateElement($string[0])
        $child.InnerText = ""
        AppendChild -string ($string | Select -Skip 1) -obj $child -XML $XML
        $obj.AppendChild($child)
    }
}

$string = "this is a somewhat long string" -split " "

$XML = New-Object System.Xml.XmlDocument
$root = $XML.CreateElement($string[0])

AppendChild -string ($string | Select -Skip 1) -obj $root -XML $XML

$root.OuterXml # 


Any suggestions?

Solution

I don't think you need recursion. Just a simple loop will do. We can just keep a reference to the last element in the document, which we update every time we append a new element, and we keep appending to that.

$tagNames = "this     is a somewhat long string" -split "\s+"
$XML = New-Object System.Xml.XmlDocument

$lastElt = $XML

$tagNames | % { 
    $elt = $XML.CreateElement($_)
    $lastElt = $lastElt.AppendChild($elt)
}

$xml.OuterXml # 


I also changed it to split the string on \s+, which is a regular expression meaning "one or whitespace characters", so that multiple consecutive spaces (or tabs or whatever) will be counted as a single thing as far as -split is concerned.

I change $string to $tagNames because it is important to name variables accurately otherwise you will confuse yourself.

Code Snippets

$tagNames = "this     is a somewhat long string" -split "\s+"
$XML = New-Object System.Xml.XmlDocument

$lastElt = $XML

$tagNames | % { 
    $elt = $XML.CreateElement($_)
    $lastElt = $lastElt.AppendChild($elt)
}

$xml.OuterXml # <this><is><a><somewhat><long><string /></long></somewhat></a></is></this>

Context

StackExchange Code Review Q#126820, answer score: 3

Revisions (0)

No revisions yet.