I am trying to convert a standard XML document to that is stored in a series of folder aggregate them together to build an automated patching system. XML document format offer the best mix of flexibility/ease of use. Unfortunately, the XML subsystem of PowerShell is case sensitive once the XML document is formatted which can leave room for unnecessary headaches so I am trying to convert the imported XML documents to PSCustomObjects but I am stuck.
I am unable to find a way to get it to detect if there are child nodes for a specific property so I can reiterate through the Convert-XMLtoArray
again so it will convert all of the XML child nodes to PSCustomObjects.
Result:
Application Version InstallType Installers ----------- ------- ----------- ---------- Mozilla Firefox 64.0.2 Install
Expected result:
Application Version InstallType Installers ----------- ------- ----------- ---------- Mozilla Firefox 64.0.2 Install {Windows 10,Windows7...}
Code:
function Convert-XmltoArray($xml) {
$Return = New-Object -TypeName 'PSCustomObject'
$XML | Get-Member -MemberType Property | ForEach {
$Property = New-Object -TypeName 'PSCustomObject'
$Name = $_.name
$Value = $XML.($Name)
if ($Value.HasChildNodes) {
foreach ($Child in $Value.ChildNodes) {
$Return | Add-Member -Type NoteProperty -Name $Child.localname -Value $($Child.'#text')
#<SomethingHere>
}
}
}
$Return
}
$Test = [XML]@"
<Package>
<Application>Java</Application>
<Version>8.2.9.23</Version>
<InstallType>Install</InstallType>
<Installers>
<Windows10>
<x86>
<File1>
<FileName>jre-8u201-windows-i586.exe</FileName>
<Parameters>/s</Parameters>
</File1>
</x86>
<x64>
<file1>
<FileName>jre-8u201-windows-x64.exe</FileName>
<Parameters>/s</Parameters>
</file1>
</x64>
<IA64>
<File1>
<FileName></FileName>
<Parameters></Parameters>
<CustomSuccessCodes></CustomSuccessCodes>
<CustomErrorCodes></CustomErrorCodes>
</File1>
</IA64>
</Windows10>
<Windows7>
<x86>
<File1>
<FileName>jre-8u201-windows-i586.exe</FileName>
<Parameters>/s</Parameters>
</File1>
</x86>
<x64>
<file1>
<FileName>jre-8u201-windows-x64.exe</FileName>
<Parameters>/s</Parameters>
</file1>
</x64>
<IA64>
<File1>
<FileName></FileName>
<Parameters></Parameters>
<CustomSuccessCodes></CustomSuccessCodes>
<CustomErrorCodes></CustomErrorCodes>
</File1>
</IA64>
</Windows7>
</Installers>
</Package>
"@
$Result = Convert-XMLToArray -xml $test
$Result
Update
Finally got it figured out, its even compatible with PSv2.
Function Convert-XMLtoPSObject {
Param (
$XML
)
$Return = New-Object -TypeName PSCustomObject
$xml |Get-Member -MemberType Property |Where-Object {$_.MemberType -EQ "Property"} |ForEach {
IF ($_.Definition -Match "^\bstring\b.*$") {
$Return | Add-Member -MemberType NoteProperty -Name $($_.Name) -Value $($XML.($_.Name))
} ElseIf ($_.Definition -Match "^\System.Xml.XmlElement\b.*$") {
$Return | Add-Member -MemberType NoteProperty -Name $($_.Name) -Value $(Convert-XMLtoPSObject -XML $($XML.($_.Name)))
} Else {
Write-Host " Unrecognized Type: $($_.Name)='$($_.Definition)'"
}
}
$Return
}