PowerShell下JSON转plist工具问题咨询:复杂JSON转换异常
I've run into similar problems with the PwshJSONtoPList script when dealing with nested JSON structures like dictionaries and object arrays—it tends to serialize those complex types as raw strings instead of converting them to proper plist <dict> or <array> elements. Here's how you can fix this:
Custom Recursive Conversion Function
Instead of relying on the limited script, you can build your own PowerShell function that recursively handles all JSON data types and outputs valid plist XML. This will properly parse nested objects, arrays, booleans, and strings:
function ConvertTo-Plist { [CmdletBinding()] param( [Parameter(ValueFromPipeline=$true)] $InputObject, [string]$Indent = "`t", [string]$OutputEncoding = "UTF-8" ) begin { $indentLevel = 0 # Helper to write lines with proper indentation function Write-Indented { param([string]$Content) Write-Output "$($Indent * $indentLevel)$Content" } # Recursive function to process any input type function Process-Item { param($Item) $indentLevel++ switch ($Item.GetType().Name) { "PSCustomObject" { Write-Indented "<dict>" foreach ($prop in $Item.PSObject.Properties) { Write-Indented "<key>$($prop.Name)</key>" Process-Item $prop.Value } $indentLevel-- Write-Indented "</dict>" } "Object[]" { Write-Indented "<array>" foreach ($element in $Item) { Process-Item $element } $indentLevel-- Write-Indented "</array>" } "Boolean" { Write-Indented $(if ($Item) { "<true/>" } else { "<false/>" }) } "Int32", "Double" { Write-Indented "<integer>$Item</integer>" } $null { Write-Indented "<null/>" } default { # Escape XML special characters in strings $escapedString = [System.Security.SecurityElement]::Escape($Item.ToString()) Write-Indented "<string>$escapedString</string>" } } } } process { # Output plist header Write-Output '<?xml version="1.0" encoding="UTF-8"?>' Write-Output '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' Write-Output '<plist version="1.0">' # Process the input JSON object Process-Item $InputObject Write-Output '</plist>' } }
How to Use This Function
Replace your existing script with this workflow:
# Read your JSON file, parse it, convert to plist, and save Get-Content "test.json" | ConvertFrom-Json | ConvertTo-Plist -Indent "`t" | Set-Content 'Generated.plist' -Encoding UTF8
What This Fixes
With this function, your problematic sections will now render correctly:
- The
Fixesnested object becomes a proper<dict>instead of a string - Arrays like
PatchesandEntrieswill contain nested<dict>elements for each item - All boolean values, numbers, and strings are serialized to their correct plist equivalents
Optional: Use a Robust .NET Library
If you need support for more edge cases (like dates, binary data, or advanced plist types), you can use a .NET library like Plist.NET. To use it in PowerShell:
- Download the library's DLL manually
- Load the assembly and use its serialization methods:
Add-Type -Path "Plist.dll" $jsonObject = Get-Content "test.json" | ConvertFrom-Json $plistBytes = [Plist.PlistSerializer]::Serialize($jsonObject) [System.IO.File]::WriteAllBytes("Generated.plist", $plistBytes)
This will handle even more complex scenarios with full plist specification compliance.
内容的提问来源于stack exchange,提问作者tianyi

