2

I want to convert multiple XML files with the same XML attribute format to a JSON file using a PowerShell script. The idea is to create a JSON list with each item being the JSON representation of the XML file. Is it doable? An example of input and output:

Input:

File1.xml:

<File>
<Child1> First xml child 1</Child1>
<Child2>First xml child 2</Child2>
</File>

File2.xml:

<File>
<Child1> Second xml child 1</Child1>
<Child2>Second xml child 2</Child2>
</File>

Output:

[
  {
    File: [
      {Child1 : First xml child 1 },
      { Child2: First xml child 2}
    ]
  },
  {
    File: [
      {Child1 : Second xml child 1 },
      { Child2: Second xml child 2}
    ]
  }
]
1
  • 3
    "Is it doable?" Sure it is. But SO is not a place where other people write code for you. What have you tried so far (show your code), and what specific problem (in your code) do you need help with? Commented Mar 6, 2017 at 22:27

3 Answers 3

3

The following uses a helper function, ConvertFrom-Xml, to convert only very simple XML documents such as your sample documents to nested hashtables with ordered keys, which can then be converted to JSON with ConvertTo-Json:

# Helper function that converts a *simple* XML document to a nested hashtable
# with ordered keys.
function ConvertFrom-Xml {
  param([parameter(Mandatory, ValueFromPipeline)] [System.Xml.XmlNode] $node)
  process {
    if ($node.DocumentElement) { $node = $node.DocumentElement }
    $oht = [ordered] @{}
    $name = $node.Name
    if ($node.FirstChild -is [system.xml.xmltext]) {
      $oht.$name = $node.FirstChild.InnerText
    } else {
      $oht.$name = New-Object System.Collections.ArrayList 
      foreach ($child in $node.ChildNodes) {
        $null = $oht.$name.Add((ConvertFrom-Xml $child))
      }
    }
    $oht
  }
}

[xml[]] (Get-Content -Raw file[12].xml) | ConvertFrom-Xml | ConvertTo-Json -Depth 3

With your sample files, this yields:

[
    {
        "File":  [
                     {
                         "Child1":  " First xml child 1"
                     },
                     {
                         "Child2":  "First xml child 2"
                     }
                 ]
    },
    {
        "File":  [
                     {
                         "Child1":  " Second xml child 1"
                     },
                     {
                         "Child2":  "Second xml child 2"
                     }
                 ]
    }
]
Sign up to request clarification or add additional context in comments.

Comments

3

In Powershell 7, this works for me:

get-content file.xml

<node>
  <subnode attrib="this">hi</subnode>
</node>


[xml]$xml = get-content file.xml                             

[Newtonsoft.Json.JsonConvert]::SerializeXmlNode($xml)

{"node":{"subnode":{"@attrib":"this","#text":"hi"}}}

1 Comment

Definitely an alternative worth considering in general, though (by default) not available in Windows PowerShell (PowerShell versions up to v5.1); in the case at hand, it would create a different representation than requested in the question.
0

Write your own formatting top of this

// To convert an XML node contained in string xml into a JSON string   
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(doc);

4 Comments

or use the built-in JavaScriptSerializer to do not depend on external packages, in PowerShell it might become tricky
Alluringly simple. I'm not sure why the OP added the C# tag to their question, but from the question text it is clear that they want a PowerShell script. So, how do you turn this into a PowerShell script? What are the full type names, and are all types preinstalled, or do you need to download dependencies, ...?
@mklement0 [Newtonsoft.Json.JsonConvert]::SerializeXmlNode($xml)
Thanks, @js2010. My comment was meant to encourage SGRao to update their answer to provide such information. Note that the NewtonSoft.Json assembly doesn't come with Windows PowerShell (it does with PowerShell [Core]). I encourage you to post your own answer that shows a full PowerShell example and background information about the assembly availability / how to get it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.