【问题标题】:Powershell convert json string to xml string always produces System.StringPowershell 将 json 字符串转换为 xml 字符串总是产生 System.String
【发布时间】:2021-01-22 02:22:30
【问题描述】:

我搜索了很多,尝试了很多,但我没有明白这一点。

我的json字符串{"transactionId":411648956,"status":1123} 总是转换为

<?xml version="1.0" encoding="utf-8"?> <Objects> <Object Type="System.String">{"transactionId":411648956,"status":1123}</Object> </Objects>

只包含我的字符串,但没有 xml。

我想要这个结果:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <status>1123</status>
   <transactionId>411648956</transactionId>
</root>

这是我尝试过但没有成功的一些代码

 $jsonline = '{"transactionId":411648956,"status":1123}'
 echo 1--------- $jsonline

 $xmlline = ConvertTo-Xml -as String $jsonline -Depth 3
 echo 5--------- $xmlline

 $jsonobj =  ConvertTo-Json $jsonline  -Depth 3
 echo 10--------- $jsonobj

 $xmlline2 = ConvertTo-Xml -as String $jsonobj -Depth 3
 echo 15--------- $xmlline2

 $jsonobj2 = $jsonline | ConvertTo-Json
 echo 20--------- $jsonobj2 

 $xmlline3 = ConvertTo-Xml -as string -InputObject $jsonobj2 -Depth 10
 echo 25--------- $xmlline3

【问题讨论】:

    标签: json xml string powershell


    【解决方案1】:

    首先$jsonline 是一个字符串,而不是一个json 对象。转换为xml之前需要先转换为对象:

    $jsonline = '{"transactionId":411648956,"status":1123}'
    $json = ConvertFrom-Json $jsonline
    [xml] $xml =  ConvertTo-Xml -InputObject $json -As Document -NoTypeInformation
    

    -NoTypeInformation 参数去掉了你的字符串对象。

    之后,您需要一些 xml 操作、一些 xsl 或一些讨厌的文本操作来获得您想要的标签名称。我将展示令人讨厌的文本操作:

    $result = "<?xml version=""1.0"" encoding=""UTF-8""?>`n<root>"
    $result+= $xml.SelectNodes('//Property')|% {
        if($_.'#text') { "`n`t<{0}>{1}</{0}>" -f $_.name,$_.'#text' } else {"<$($_.name)/>"}
    }
    $result+="`n</root>"
    $result
    

    我选择节点并将它们的属性名称转换为标签名称。该代码的灵感来自@Walid2mi 对这个问题的回答:Change XML tags within PowerShell and keep content.

    【讨论】:

      【解决方案2】:

      谢谢帕莱杜。 是的,关键是使用 ConvertFrom-Json。 这是我的解决方案:

          <# Solution to convert json to pretty xml
      based on https://www.reddit.com/r/PowerShell/comments/7en74l/json_to_xml_and_back/
      using https://github.com/omrsafetyo/PowerShellSnippets/blob/master/Convert-CustomObjectToXml.ps1
      #>
      
      
      Function Convert-CustomObjectToXml {
      <#
      .SYNOPSIS
       
      Outputs a human readable simple text XML representation of a simple PS object.
       
      .PARAMETER object
       
      The input object to inspect and dump.
       
      .PARAMETER depth
       
      The number of levels deep to dump. Defaults to 1.
       
      .PARAMETER rootEl
       
      The name of the root element in the document. Defaults to "root"
       
      .PARAMETER indentString
       
      The string used to indent each level of XML. Defaults to two spaces.
      Set to "" to remove indentation.
       
      .DESCRIPTION
       
      Outputs a human readable simple text XML representation of a simple PS object.
       
      A PSObject with member types of NoteProperty will be dumped to XML.  Only
      nested PSObjects up to the depth specified will be searched. All other
      note properties will be ouput using their strings values.
       
      The output consists of node with property names and text nodes containing the
      property value.
      Original Author: http://wannemacher.us/?p=430
      Modified to include working with Object arrays, and now outputs XML instead of strings.
       
      #>
          [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 {}
      }
      
      # make json string to object
      $jsonline = '{"transactionId":411648956,"status":"OK"}'
      $jsonObject = ConvertFrom-Json –InputObject  $jsonline  
      echo $jsonObject
      echo ---------------------------
      
      
      # make object to xml 
      $xml = Convert-CustomObjectToXml -object $jsonObject -depth 99 
      echo  $xml.OuterXml
      
      # save xml with pretty print
      $xml.Save("C:\tmp\test.xml")
      

      【讨论】:

        猜你喜欢
        • 2012-10-26
        • 2013-03-02
        • 1970-01-01
        • 1970-01-01
        • 2019-10-29
        • 2016-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多