是否可以使用JsonReaderWriterFactory将XML转换为JSON而不使用DataContractJsonSerializer?

时间:2014-10-02 08:56:24

标签: json xml serialization deserialization datacontractjsonserializer

我需要一个通用例程,它接受任何有效的XML并将其转换为JSON,而不需要知道底层数据类型。我知道这可以通过Json.Net轻松完成,我也知道如何使用DataContractJsonSerializer,但我们的组织不使用Json.Net,DataContractJsonSerializer需要启用数据协定的对象类型。

我使用Json.Net的工作代码:

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

我希望能够使用的代码,使用JsonReaderWriterFactory而不是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());
}

有解决方法吗?

1 个答案:

答案 0 :(得分:2)

太糟糕了,Json.Net不是一个选择 - 我们已经使用它多年了,这太棒了。缺少本地解析和手工生成json,没有很多快速的方法可以做到这一点。

查看此链接中的代码:

这段代码很容易适应一个类甚至扩展来转换XML文档(甚至只是被解析为XML文档的xml字符串,然后返回json。

另一种需要考虑的方法可能如下。它指定使用匿名类型,假设您无法控制可以从XML反序列化的对象(并且您不想管理这些单独的类型)。

  1. 将XML转换为匿名类型(可能通过
  2. 使用JavascriptSerializer将匿名对象序列化为json
  3. 下面的代码示例显示了这个技术:

    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;
            }
        }
    }