ps/Modules/Alkami.PowerShell.Common/Public/ConvertFrom-Xml.ps1
2023-05-30 22:51:22 -07:00

64 lines
2.1 KiB
PowerShell

function ConvertFrom-Xml {
<#
.SYNOPSIS
Used to convert an object from Xml to a hashtable (think `$xml | ConvertFrom-Xml | ConvertTo-Json`)
.PARAMETER Node
Some XML node to be passed in
#>
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[System.Xml.XmlNode]$Node
)
if ($node.DocumentElement) {
$Node = $Node.DocumentElement
}
$name = $Node.Name
$orderedHashtable = [Ordered]@{ $name = [Ordered]@{} }
foreach($attribute in $Node.Attributes) {
$attributeName = $attribute.Name
$orderedHashtable.$name.$attributeName = $attribute.FirstChild.InnerText
}
foreach($child in $Node.ChildNodes) {
$childName = $child.Name
$value = $null
if ($child -is [System.Xml.XmlComment]) {
$childName = "xmlComments"
$value = $child.OuterXml
} elseif ($child -is [System.Xml.XmlText]) {
$value = $child.InnerText
$childName = $name
} else {
$value = (ConvertFrom-Xml $child).$childName
# this hackery lets an object like <elem attr="x">text</elem> become elem: { attr = x; elem = val; } but <elem>val</elem> becomes elem: val
# simple hack is best hack
# Thanks I hate it too
if (($null -ne $value.$childName) -and ($value.Keys.Count -eq 1)) {
$value = $value.$childName
} else {
$value = [PSCustomObject]$value
}
}
if ($null -eq $value) {
continue
}
if ($null -eq $orderedHashtable.$name.$childName) {
$orderedHashtable.$name.$childName = $value
} else {
# the key already exists, so we need to be using an array for the values
if (!($orderedHashtable.$name.$childName -is [Array])) {
$current = @($orderedHashtable.$name.$childName)
$orderedHashtable.$name.$childName = $current
}
$orderedHashtable.$name.$childName += $value
}
}
return [PSCustomObject]$orderedHashtable
}