我需要一个通用例程,它接受任何有效的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());
}
有解决方法吗?
答案 0 :(得分:2)
太糟糕了,Json.Net不是一个选择 - 我们已经使用它多年了,这太棒了。缺少本地解析和手工生成json,没有很多快速的方法可以做到这一点。
查看此链接中的代码:
这段代码很容易适应一个类甚至扩展来转换XML文档(甚至只是被解析为XML文档的xml字符串,然后返回json。
另一种需要考虑的方法可能如下。它指定使用匿名类型,假设您无法控制可以从XML反序列化的对象(并且您不想管理这些单独的类型)。
下面的代码示例显示了这个技术:
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;
}
}
}