Is it possible to use JsonReaderWriterFactory to convert XML to JSON without using DataContractJsonSerializer?

假装没事ソ 提交于 2019-12-24 02:18:41

问题


I need a generic routine that takes any valid XML and converts it to JSON without knowing the underlying data type. I know that this is easily done with Json.Net and I also know how to do it with the DataContractJsonSerializer but our organisation doesn't use Json.Net and the DataContractJsonSerializer needs a Data Contract enabled object type.

My working code using Json.Net:

XmlDocument document = new XmlDocument();
document.LoadXml(xml);
string jsonText = JsonConvert.SerializeXmlNode(document);

The code I'd like to be able to use, using JsonReaderWriterFactory instead of Json.Net:

string jsonText = string.Empty;

MemoryStream stream = new MemoryStream();
StreamWriter streamWriter = new StreamWriter(stream);
streamWriter.Write(xml);
streamWriter.Flush();
stream.Position = 0;

using (XmlDictionaryWriter xmlWriter = JsonReaderWriterFactory.CreateJsonWriter(stream))
{
    object someObject = new object();
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(someObject.GetType());
    serializer.WriteObject(stream, someObject);
    xmlWriter.Flush();
    jsonText = Encoding.Default.GetString(stream.GetBuffer());
}

Is there a way around this?


回答1:


Too bad the Json.Net isn't an option - we've used it for years now, and it's fantastic. Short of native parsing and json generation by hand, there's not a lot of fast ways to do this.

Check out the code from this link:

  • http://www.phdcc.com/xml2json.htm (See section "XmlToJSON C# code", should be fairly quick)

This code could easily be adapted to a class or even extension to convert an XML Document (or even just xml string being parsed into an XML document, then returning the json.

Another approach to consider could be the following. It specifies using anonymous types assuming you don't have control of the objects that could be deserialized from XML (and you don't want to manage those separate types).

  1. Convert the XML into an anonymous type (probably through the
  2. Use the JavascriptSerializer to serialize the anonymous object into the json

The code sample below shows this techinique:

using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Data.Entity.Design.PluralizationServices;
using System.Globalization;

namespace Scratch
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = "<root><student><id>1</id></student><student><id>2</id></student></root>";
            string json = XmlToJson(xml);
            Console.WriteLine(json);
            Console.ReadKey(true);
        }

        // Using JavaScriptSerializer
        static string XmlToJson(string xml)
        {
            var obj = GetAnonymousType(xml);
            var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            return serializer.Serialize(obj);
        }

        // Adapted from: http://www.codeproject.com/Tips/227139/Converting-XML-to-an-dynamic-object-using-ExpandoO
        static dynamic GetAnonymousType(string xml, XElement node = null)
        {
            node = string.IsNullOrEmpty(xml) ? node : XDocument.Parse(xml).Root;
            IDictionary<String, dynamic> result = new ExpandoObject();
            var pluralizationService = PluralizationService.CreateService(CultureInfo.CreateSpecificCulture("en-us"));
            node.Elements().AsParallel().ForAll(gn =>
                {
                    var isCollection = gn.HasElements
                        && (gn.Elements().Count() > 1
                            && gn.Elements().All(e => e.Name.LocalName.ToLower() == gn.Elements().First().Name.LocalName)
                        || gn.Name.LocalName.ToLower() == pluralizationService.Pluralize(gn.Elements().First().Name.LocalName).ToLower());
                    var items = isCollection ? gn.Elements().ToList() : new List<XElement>() { gn };
                    var values = new List<dynamic>();
                    items.AsParallel().ForAll(i => values.Add((i.HasElements) ? GetAnonymousType(null, i) : i.Value.Trim()));
                    result[gn.Name.LocalName] = isCollection ? values : values.FirstOrDefault();
                });
            return result;
        }
    }
}


来源:https://stackoverflow.com/questions/26157441/is-it-possible-to-use-jsonreaderwriterfactory-to-convert-xml-to-json-without-usi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!