Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert *.RESX XML file to JSON file in C#

Tags:

json

xml

c#-7.0

How can I convert *.RESX XML file to JSON file in C#?

I have regular RESX file. For example:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
    <xsd:element name="root" msdata:IsDataSet="true">
      <xsd:complexType>
        <xsd:choice maxOccurs="unbounded">
          <xsd:element name="metadata">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" />
              </xsd:sequence>
              <xsd:attribute name="name" use="required" type="xsd:string" />
              <xsd:attribute name="type" type="xsd:string" />
              <xsd:attribute name="mimetype" type="xsd:string" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="assembly">
            <xsd:complexType>
              <xsd:attribute name="alias" type="xsd:string" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="data">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
              <xsd:attribute ref="xml:space" />
            </xsd:complexType>
          </xsd:element>
          <xsd:element name="resheader">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
              </xsd:sequence>
              <xsd:attribute name="name" type="xsd:string" use="required" />
            </xsd:complexType>
          </xsd:element>
        </xsd:choice>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <resheader name="resmimetype">
    <value>text/microsoft-resx</value>
  </resheader>
  <resheader name="version">
    <value>2.0</value>
  </resheader>
  <resheader name="reader">
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name="writer">
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
    <data xml:space="preserve" name="KEY_1">       
        <value>Text A</value>
    </data>
    <data xml:space="preserve" name="KEY_2">       
        <value>Text B</value>
    </data>
</root>

I need to convert this file to JSON file:

{
  "Texts": [
    {
      "id": "KEY_1",
      "text": "Text A"
    },
    {
      "id": "KEY_2",
      "text": "Text B"
    }
  ]
}

As you can see for conversion is relevant only part with data:

    <data xml:space="preserve" name="KEY_1">       
        <value>Text A</value>
    </data>
    <data xml:space="preserve" name="KEY_2">       
        <value>Text B</value>
    </data>

Everything else is irrelevant for transformation.

  1. Name in data attribute XML => is id in JSON file.
  2. Value in XML=> is text in JSON file.

EDIT: I have solution, but I think that it can be done better

using System.Xml;
using System.IO;
using System.Collections.Generic;
using System.Linq;

namespace XMLtoJSON
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> result = new Dictionary<string, string>();
            // To convert an XML node contained in string xml into a JSON string 
            var xml = File.ReadAllText(@"C:\Test\ClientLocalization.en-US.resx");
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            XmlNodeList node = doc.GetElementsByTagName("data");
            foreach (XmlNode item in node)
            {
                var value = item.InnerText.Trim();
                var keyName = item.Attributes.Cast<XmlAttribute>().FirstOrDefault(f => f.Name == "name");
                if (keyName != null)
                {
                    var key = keyName.InnerText.Trim();
                    result.Add(key, value);
                }
            }

            string res = @"{ ""Text"" : [ ";
            foreach (var item in result)
            {
                res += "{";
                res += $" \"id\":\"{item.Key}\",\"text\":\"{item.Value}\"";
                res += "},";
            }
            res = res.Remove(res.Length - 1);
            res += @" ]} ";
        }

    }
}
like image 362
Raskolnikov Avatar asked Dec 04 '17 10:12

Raskolnikov


People also ask

Is Resx an XML?

resx resource file format consists of XML entries that specify objects and strings inside XML tags. One advantage of a . resx file is that when opened with a text editor (such as Notepad) it can be written to, parsed, and manipulated.

Can we convert JSON to XML in C#?

Click Tools=> NuGet Package Manager=> Package Manager Console. Type “PM> Install-Package Newtonsoft. Json”. DeserializeXmlNode() is the helper method to convert JSON to XML.

How do I open a RESX file?

Open a . resx file in the XML (Text) editor. Press Ctrl+Alt+F or choose ReSharper | Windows | File Structure from the main menu . Alternatively, you can press Ctrl+Shift+A , start typing the command name in the popup, and then choose it there.


2 Answers

Instead of using XmlDocument, I would use XElement as it is much more LINQ-friendly. Use XElement.Parse to load the XML, then select the nodes you are interested in and shape them into an anonymous object structure that mirrors the JSON you want. Finally, use your favorite JSON serializer (such as Json.Net or JavaScriptSerializer) to create the JSON from there. I don't recommend hand-rolling your own JSON, as it is very error prone.

using Newtonsoft.Json;

var xml = File.ReadAllText(@"C:\Test\ClientLocalization.en-US.resx");

var obj = new
{
    Texts = XElement.Parse(xml)
        .Elements("data")
        .Select(el => new
        {
            id = el.Attribute("name").Value,
            text = el.Element("value").Value.Trim()
        })
        .ToList()
};

string json = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented);

// OR:
//JavaScriptSerializer jss = new JavaScriptSerializer();
//string json = jss.Serialize(obj);

Console.WriteLine(json);

Fiddle: https://dotnetfiddle.net/ZIaCjd

like image 104
Brian Rogers Avatar answered Oct 10 '22 07:10

Brian Rogers


I'd recommend you the JSON.NET Framework. It has built-in functions for converting XML to JSON and vice versa.

Example:

string xml = @"<?xml version='1.0' standalone='no'?>
<root>
  <person id='1'>
    <name>Alan</name>
    <url>http://www.google.com</url>
  </person>
  <person id='2'>
    <name>Louis</name>
    <url>http://www.yahoo.com</url>
  </person>
</root>";

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

string jsonText = JsonConvert.SerializeXmlNode(doc);
//{
//  "?xml": {
//    "@version": "1.0",
//    "@standalone": "no"
//  },
//  "root": {
//    "person": [
//      {
//        "@id": "1",
//        "name": "Alan",
//        "url": "http://www.google.com"
//      },
//      {
//        "@id": "2",
//        "name": "Louis",
//        "url": "http://www.yahoo.com"
//      }
//    ]
//  }
//}
like image 20
Maurice Avatar answered Oct 10 '22 05:10

Maurice