Reputation: 11
I am trying to merge 3 xml files into 1 using PowerShell. I have tried a number of ways using Select-Xml, CreateElement followed by AppendChild etc but can't seem to understand how to get the elements I want to be included correctly into s new XML Document. I either get an empty resultant file or System.Xml.Element in the nodes.
The three files have the contents: File A
<?xml version="1.0" encoding="utf-8"?>
<ResourceResponse>
<Status>Success</Status>
<Resource id="12345" name="aName" description="Microsoft Windows 2008" location="" instanceId="10003" typeId="1">
<Agent id="23456" address="x.x.x.x" port="2144" version="x.x.x" unidirectional="false" />
<Ip address="x.x.x.x" netmask="255.0.0.0" mac="00:00:00:00:00:00" />
<Ip address="x.x.x.x" netmask="255.255.240.0" mac="00:50:56:03:40:E2" />
<ResourceInfo key="fqdn" value="aName.here.lo" />
</Resource>
</ResourceResponse>
File B
<?xml version="1.0" encoding="utf-8"?>
<ResourcePrototypeResponse>
<Status>Success</Status>
<ResourcePrototype instanceId='10164' resourceTypeId='3' id='10213' name='TCP Socket'/>
</ResourcePrototypeResponse>
File C
<?xml version="1.0" encoding="utf-8"?>
<Resource name="SocketHTTP">
<ResourceConfig key="hostname" value="localhost"/>
<ResourceConfig key="port" value="80"/>
<ResourceConfig key="sotimeout" value="10"/>
<ResourceConfig key="service.log_track.enable" value="false"/>
<ResourceConfig key="service.log_track.level" value="Error"/>
<ResourceConfig key="service.log_track.include" value=""/>
<ResourceConfig key="service.log_track.exclude" value=""/>
<ResourceInfo key="autoIdentifier" value="SocketHTTP"/>
</Resource>
I would like the created file to look like:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CreateResourceRequest>
<Resource id="12345" name="aName" description="Microsoft Windows 2008" location="" instanceId="10087" typeId="1">
<Agent id="23456" address="x.x.x.x" port="2144" version="x.x.x" unidirectional="false"/>
<Ip address="x.x.x.x" netmask="255.255.255.0"/>
<Ip address="x.x.x.x" netmask="255.0.0.0"/>
<ResourceInfo key="fqdn" value="aName.here.lo"/>
</Resource>
<ResourcePrototype instanceId="10164" resourceTypeId="3" id="10213" name="TCP Socket"/>
<Resource name="SocketHTTP">
<ResourceConfig key="hostname" value="target.here.lo"/>
<ResourceConfig key="port" value="80"/>
<ResourceConfig key="sotimeout" value="10"/>
<ResourceConfig key="service.log_track.enable" value="false"/>
<ResourceConfig key="service.log_track.level" value="Error"/>
<ResourceConfig key="service.log_track.include" value=""/>
<ResourceConfig key="service.log_track.exclude" value=""/>
<ResourceInfo key="autoIdentifier" value="SocketHTTP"/>
</Resource>
</CreateResourceRequest>
Thanks in advance, I'm stumped....
Upvotes: 1
Views: 2991
Reputation: 3275
You need something like this:
function Add-XmlFromFile ([String]$Path,
[String]$XPath,
[System.Xml.XmlElement]$ParentElement) {
[System.Xml.XmlElement]$ChildElement = `
(Select-Xml -Path $Path -XPath $XPath).Node
[System.Xml.XmlElement]$ImportedElement = `
$ParentElement.OwnerDocument.ImportNode($ChildElement, $true)
return $ParentElement.AppendChild($ImportedElement)
}
# Creating new XML object.
$Xml = New-Object Xml
$XmlDeclaration = $Xml.CreateXmlDeclaration("1.0", "UTF-8", $null)
$Xml.AppendChild($XmlDeclaration) | Out-Null
# Creating parent element.
$CreateResourceRequest = $Xml.CreateElement("CreateResourceRequest")
# Adding child elements to parent.
Add-XmlFromFile -Path "File A.xml" `
-XPath "//ResourceResponse/Resource" `
-ParentElement $CreateResourceRequest | Out-Null
Add-XmlFromFile -Path "File B.xml" `
-XPath "//ResourcePrototypeResponse/ResourcePrototype" `
-ParentElement $CreateResourceRequest | Out-Null
Add-XmlFromFile -Path "File C.xml" `
-XPath "//Resource" `
-ParentElement $CreateResourceRequest | Out-Null
# Appending parent to XML object.
$Xml.AppendChild($CreateResourceRequest) | Out-Null
# Saving XML object.
$Xml.OuterXml | Out-File -FilePath "File D.xml" -Encoding "UTF8"
Upvotes: 2