Build/ConvertXmlToJson.ps1
|
#!/usr/bin/env powershell <# .SYNOPSIS Converts PatchMyPC.xml catalog to JSON format .DESCRIPTION Extracts software update information from PatchMyPC.xml and creates a JSON file with Title, TargetProductCode, and ObsoletedPatches for each update. .PARAMETER XmlPath Path to the source PatchMyPC.xml file .PARAMETER JsonPath Path to the output JSON file .PARAMETER RemoveVersionNumbers If $true, removes version numbers from titles (default: $true) .PARAMETER RemoveDuplicates If $true, removes duplicate entries from TargetProductCode arrays (default: $true) .EXAMPLE .\ConvertXmlToJson.ps1 -XmlPath '.\PatchMyPC.xml' -JsonPath '.\AdobeAcrobat.json' #> param( [Parameter(Mandatory = $false)] [string]$XmlPath = ".\PatchMyPC.xml", [Parameter(Mandatory = $false)] [string]$JsonPath = ".\AdobeAcrobat.json", [switch]$RemoveVersionNumbers = $true, [switch]$RemoveDuplicates = $true ) # Validate input file exists if (-not (Test-Path $XmlPath)) { Write-Error "XML file not found: $XmlPath" exit 1 } # Load XML [xml]$xml = Get-Content $XmlPath $updates = @() # Navigate directly through the XML structure without relying on namespace prefixes # The XML structure is: SoftwareDistributionPackage > LocalizedProperties (for title) and InstallableItem (for codes/patches) $rootNode = $xml.DocumentElement # Process each SoftwareDistributionPackage $packages = $rootNode.ChildNodes | Where-Object { $_.LocalName -eq "SoftwareDistributionPackage" } foreach ($package in $packages) { $title = "" $productCodes = @() $obsoletedPatches = @() # Get title from LocalizedProperties $localizedPropsList = $package.ChildNodes | Where-Object { $_.LocalName -eq "LocalizedProperties" } foreach ($localizedProps in $localizedPropsList) { $titleNode = $localizedProps.ChildNodes | Where-Object { $_.LocalName -eq "Title" } if ($titleNode) { $title = $titleNode.InnerText break } } # Get product codes and obsoleted patches from InstallableItem > Metadata > MsiPatch $installableItems = $package.ChildNodes | Where-Object { $_.LocalName -eq "InstallableItem" } foreach ($item in $installableItems) { $applicabilityRules = $item.ChildNodes | Where-Object { $_.LocalName -eq "ApplicabilityRules" } foreach ($rule in $applicabilityRules) { $metadata = $rule.ChildNodes | Where-Object { $_.LocalName -eq "Metadata" } foreach ($meta in $metadata) { $msiPatchMetadata = $meta.ChildNodes | Where-Object { $_.LocalName -eq "MsiPatchMetadata" } foreach ($msiMeta in $msiPatchMetadata) { $msiPatch = $msiMeta.ChildNodes | Where-Object { $_.LocalName -eq "MsiPatch" } foreach ($patch in $msiPatch) { # Extract TargetProductCode(s) $tpcNodes = $patch.ChildNodes | Where-Object { $_.LocalName -eq "TargetProductCode" } foreach ($tpcNode in $tpcNodes) { $productCodes += $tpcNode.InnerText } # Extract TargetProduct/TargetProductCode(s) $targetProducts = $patch.ChildNodes | Where-Object { $_.LocalName -eq "TargetProduct" } foreach ($targetProduct in $targetProducts) { $tpChildNodes = $targetProduct.ChildNodes | Where-Object { $_.LocalName -eq "TargetProductCode" } foreach ($tpChild in $tpChildNodes) { $productCodes += $tpChild.InnerText } } # Extract ObsoletedPatch entries $obsoleteNodes = $patch.ChildNodes | Where-Object { $_.LocalName -eq "ObsoletedPatch" } foreach ($obsoleteNode in $obsoleteNodes) { $obsoletedPatches += $obsoleteNode.InnerText } } } } } } # Remove duplicates if requested if ($RemoveDuplicates) { $productCodes = @($productCodes | Select-Object -Unique) } # Remove version numbers from title if requested $cleanTitle = $title if ($RemoveVersionNumbers) { $cleanTitle = $cleanTitle -replace '\s+\d+\.\d+\.\d+', '' } # Only create entry if we have a title and product codes if ($cleanTitle -and $productCodes.Count -gt 0) { $updateObj = [PSCustomObject]@{ Title = $cleanTitle TargetProductCode = $productCodes ObsoletedPatches = $obsoletedPatches } $updates += $updateObj } } # Convert to JSON and save $json = $updates | ConvertTo-Json -Depth 10 $json | Set-Content $JsonPath -Encoding UTF8 Write-Host "Conversion complete!" Write-Host " Source: $XmlPath" Write-Host " Destination: $JsonPath" Write-Host " Records: $($updates.Count)" Write-Host " Remove Duplicates: $RemoveDuplicates" Write-Host " Remove Version Numbers: $RemoveVersionNumbers" |