我需要一个通用例程,它可以接受任何有效的 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());
}
有办法解决这个问题吗?
最佳答案
可惜 Json.Net 不是一个选择 - 我们已经使用它很多年了,它非常棒。由于缺少本地解析和手动生成 json,因此没有很多快速方法可以做到这一点。
查看此链接中的代码:
- http://www.phdcc.com/xml2json.htm (请参阅“XmlToJSON C# 代码”部分,应该相当快)
此代码可以轻松地适应类甚至扩展以转换 XML 文档(甚至只是将 xml 字符串解析为 XML 文档,然后返回 json。
另一种可以考虑的方法如下。它指定使用匿名类型,假设您无法控制可以从 XML 反序列化的对象(并且您不想管理这些单独的类型)。
- 将 XML 转换为匿名类型(可能通过
- 使用JavascriptSerializer将匿名对象序列化为json
下面的代码示例展示了这种技术:
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;
}
}
}
关于json - 是否可以使用 JsonReaderWriterFactory 将 XML 转换为 JSON,而不使用 DataContractJsonSerializer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26157441/