2

我需要一個通用例程,它接受任何有效的XML並將其轉換爲JSON而無需知道底層數據類型。我知道這很容易用Json.Net完成,我也知道如何用DataContractJsonSerializer來完成,但是我們的組織不使用Json.Net,並且DataContractJsonSerializer需要啓用數據協定的對象類型。使用Json.Net是否可以使用JsonReaderWriterFactory將XML轉換爲JSON而不使用DataContractJsonSerializer?

我的工作代碼:

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

我希望能夠使用,使用替代Json.Net JsonReaderWriterFactory代碼:

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

是否有辦法在這附近?

回答

2

太糟糕了,Json.Net不是一種選擇 - 我們已經使用了很多年了,而且太棒了。手工解析和生成json代碼很短,沒有很多快速的方法來做到這一點。

退房從這個鏈接的代碼:

該代碼可以很容易地適應一類,甚至擴展來轉換一個XML文檔(或者甚至只是將xml字符串解析成XML文檔,然後返回json)

另一種考慮的方法可能如下:它指定使用匿名類型,假設你d沒有控制可以從XML反序列化的對象(並且你不想管理這些單獨的類型)。

  1. 轉換的XML到匿名類型(可能通過
  2. 使用JavascriptSerializer序列化匿名對象到JSON

下面的代碼樣本顯示了這個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; 
     } 
    } 
} 
+0

這種匿名類型的方法非常適合我想要做的事。感謝您的幫助! – 2014-10-20 09:02:24

相關問題