简体   繁体   中英

Convert JSON FILE to XML FILE using POWERSHELL

I need to convert Json file from web to xml file and i need very simple way... There are several data I need from Json response... There are a lot of around but they are not very clear. I found some samples like this:

PS c:\0> ConvertTo-Xml -InputObject temp_JSON.json -As String   

PS c:\0> ConvertTo-Xml -InputObject temp_JSON.json -As document

but I can't see or find result... Where I'm wrong.

this is Json response string to convert:

"{"data":[{"id":"86xEyb****lUsw==","custom_fields":{"firstName":"Z***n","lastName":"Pe***ki","locale":"EN-GB_MK","timezone":"8","gender":"N\/A","phone":"+38***6","email":null},"tags":[],"created_at":1600276472}],"links":{"first":"http:\/\/app.respond.io\/api\/v1\/contact\/by_custom_field?name=firstName&value=zoran&page=1","last":"http:\/\/app.respond.io\/api\/v1\/contact\/by_custom_field?name=firstName&value=zoran&page=1","prev":null,"next":null},"meta":{"current_page":1,"from":1,"last_page":1,"path":"http:\/\/app.respond.io\/api\/v1\/contact\/by_custom_field","per_page":10,"to":1,"total":1}}"

@Guenther Schmitz answer works perfect, But I need some more to ask about style of xml. I receive output like

<Objects>
   <Object Type="System.Management.Automation.PSCustomObject">
      <Property Name="data" Type="System.Object[]">
         <Property Type="System.Management.Automation.PSCustomObject">
            <Property Name="id" Type="System.String">*******</Property>
         <Property Name="custom_fields"  Type="System.Management.Automation.PSCustomObject">
             <Property Name="firstName" Type="System.String">B***</Property>
             <Property Name="lastName" Type="System.String">B***</Property> ... 

But I tried conversion at Json to xml web converters and I got another xml format, which is more convenient to me, I need to import data to database and I need simple xml format, so I need that way like:

<?xml version="1.0" encoding="UTF-8" ?>
<root>
  <data>
    <id>nh****93UhUrQ==</id>
    <custom_fields>
      <firstName>BI**NA</firstName>
      <lastName>B**AK</lastName>
      <locale>EN_MK</locale> ...

Is it possible to get another xml output style.

In mean time time I founded that if you add this parameter:

-notypeinformation
it will clear up types from xml, so the line would be:
$XML = ConvertTo-Xml -As Stream -InputObject $JsonObject -Depth 3 -notypeinformation

But still remain: <Property Name="firstName"... instead name

you first have to convert the json-file to a PowerShell Object like

$JsonObject = Get-Content -Path "C:\path\to\temp_JSON.json" | ConvertFrom-Json

this can then be used for the parameter InputObject

$XML = ConvertTo-Xml -As Stream -InputObject $JsonObject -Depth 3

Note the parameter Depth . You might have to play around with this one depending on your structure as the default value is 1. See the documentation for reference.

the resulting XML Object can then be saved to a file using the command Out-File

Out-File -FilePath "C:\path\to\temp_XML.xml" -InputObject $XML 

this can also be done in one line through piping.

Get-Content -Path "C:\path\to\temp_JSON.json" | ConvertFrom-Json | ConvertTo-Xml -As Stream -Depth 3 | Out-File -FilePath "C:\path\to\temp_XML.xml"

I think the best solution to have specific nodes instead of Property nodes you should the following custom function Convert-CustomObjectToXml

This snippet was originally done by Eric Wannemacher Blog and then improved by Nathan Kulas

Function Convert-CustomObjectToXml {
    [CmdletBinding()]
    param (
        [PSCustomObject]$object,
        [Int32]$depth = 1,
        [String]$rootEl = "root",
        [String]$indentString = "  ",
        [Int32]$indent = 1,
        [switch]$isRoot = $true,
        [String]$XmlVersion = "1.0",
        [String]$Encoding = "UTF-8"
    )
    BEGIN {
        $sb = [System.Text.StringBuilder]::new()
    }
    
    PROCESS {
        # Output the root element opening tag
        if ($isRoot) {
            [void]$sb.AppendLine(("<{0}>" -f $rootEl))
        }
        
        ForEach ( $item in $object ) {
            # Iterate through all of the note properties in the object.
            foreach ($prop in (Get-Member -InputObject $item -MemberType NoteProperty)) {
                $children = $item.($prop.Name)
                foreach ($child in $children) {
                    # Check if the property is an object and we want to dig into it
                    if ($child.GetType().Name -eq "PSCustomObject" -and $depth -gt 1) {
                        [void]$sb.AppendLine(("{0}<{1}>" -f ($indentString * $indent), $prop.Name))
                        Convert-CustomObjectToXml $child -isRoot:$false -indent ($indent + 1) -depth ($depth - 1) -indentString $indentString | ForEach-Object { [void]$sb.AppendLine($_) }
                        [void]$sb.AppendLine(("{0}</{1}>" -f ($indentString * $indent), $prop.Name))
                    }
                    else {
                        # output the element or elements in the case of an array
                        foreach ($element in $child) {
                            [void]$sb.AppendLine(("{0}<{1}>{2}</{1}>" -f ($indentString * $indent), $prop.Name, $element))
                        }
                    }
                }
            }
        }
     
        # If this is the root, close the root element and convert it to Xml and output
        if ($isRoot) {
            [void]$sb.AppendLine(("</{0}>" -f $rootEl))
            [xml]$Output = $sb.ToString()
            $xmlDeclaration = $Output.CreateXmlDeclaration($XmlVersion,$Encoding,$null)
            [void]$Output.InsertBefore($xmlDeclaration, $Output.DocumentElement)
            $Output
        }
        else {
            # If this is the not the root, this has been called recursively, output the string
            Write-Output $sb.ToString()
        }
    }
    END {}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM