使用PowerShell将JSON文件转换为XML文件

mbzjlibv  于 2022-11-10  发布在  Shell
关注(0)|答案(2)|浏览(165)

我需要转换JSON文件从网络到XML文件,我需要非常简单的方式…我需要从Json Response获得几个数据。周围有很多东西,但不是很清楚。我发现了一些这样的样本:

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

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

但我看不到也找不到结果。在哪里我错了。
这是要转换的Json响应字符串:

"{"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的回答很完美,但我还需要更多关于XML样式的问题。我收到的输出如下

<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> ...

但我尝试了Json到XMLWeb转换器的转换,我得到了另一种对我来说更方便的XML格式,我需要将数据导入数据库,我需要简单的XML格式,所以我需要这样的方式:

<?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> ...

是否有可能获得另一种XML输出样式。
与此同时,我发现如果你加上这个参数:

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

但仍然保留:<Property Name=“FirstName”...而不是名称

p8ekf7hl

p8ekf7hl1#

首先必须将json文件转换为PowerShell对象,如下所示

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

然后可以将其用于参数InputObject

$XML = ConvertTo-Xml -As Stream -InputObject $JsonObject -Depth 3
  • 请注意参数Depth。根据您的结构,您可能需要尝试使用此参数,因为默认值为1。请参阅documentation以供参考。*

然后,可以使用命令Out-File将生成的XML对象保存到文件中

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

这也可以通过管道在一条管道中完成。

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"
1u4esq0p

1u4esq0p2#

我认为最好的解决方案是拥有特定的节点,而不是属性节点,你应该使用以下定制函数Convert-CustomObjectToXml
此代码段最初由Eric Wannemacher Blog完成,然后由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 {}
}

相关问题