xBarns
xBarns

Reputation: 291

Creating nested XML node

I am trying to ouput the results of an API call to a predefined XML structure. I create the XML in Powershell and add the declaration and a root node.

I found the way of how to add multiple child nodes at another SO entry. Stupid enough i closed the tab this was in before writing this, so sorry i don't have the link anymore.

As you can see below, the root node is not part of the definition of where the values i query need to go, it starts one level below the root node.

Later other items will be added to the root node also.

The way i have this set up, it works with the loop adding the nodes that i want when i remark the line:

#$xmlDocument.AppendChild($xmlRoot) | Out-Null

I do get an output:

<?xml version="1.0" encoding="UTF-8"?><DEF><GHJ><GHJ /></GHJ></DEF>

that looks ok, but the root element is (obviously) missing, if i add in that remarked line, i get an error stating (translated from german) "The document already has a 'DocumentElement' node."

Expected output

<?xml version="1.0" encoding="UTF-8"?><ABC xmlns:xsi="http://www.w3.org 2001/XMLSchema-instance" noNamespaceSchemaLocation="Dummy.xsd"><DEF><GHJ><GHJ /></GHJ></DEF></ABC>

(Duplicate GHJ is on purpose)

$config = @{Output = @{Root = "ABC"}}
$targetSplit = ("DEF\GHJ\GHJ").Split("\")

# Create XML document
[xml]$xmlDocument = New-Object System.Xml.XmlDocument

# Create XML declaration
$xmlDeclaration = $xmlDocument.CreateXmlDeclaration("1.0","UTF-8",$null) 

# Add declaration to XML document
$xmlDocument.AppendChild($xmlDeclaration)

# Create root node  
$xmlRoot = $xmlDocument.CreateElement($config.Output.Root)

# Add root attributes
$xmlRoot.SetAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance')
$xmlRoot.SetAttribute('xsi:noNamespaceSchemaLocation', 'Dummy.xsd')

#add root to the document
#$xmlDocument.AppendChild($xmlRoot) | Out-Null

$lastXMLElement = $xmlDocument

for($i = 0; $i -lt $targetSplit.Length; $i++) {

    $xmlElement = $xmlDocument.CreateElement($targetSplit[$i])
    $lastXMLElement = $lastXMLElement.AppendChild($xmlElement)

}      

$xmlDocument.OuterXml

Upvotes: 0

Views: 754

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174435

Change this part, just before the loop:

#add root to the document
#$xmlDocument.AppendChild($xmlRoot) | Out-Null

$lastXMLElement = $xmlDocument

to:

#add root to the document
$lastXMLElement = $xmlDocument.AppendChild($xmlRoot)

Otherwise, appending children to $lastXMLElement would mean adding more root elements to the document, and there can only be one root node :)

Upvotes: 2

Related Questions