如何使用 C#/LINQ 将 XML 转换为 JSON?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12037085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert XML to JSON using C#/LINQ?
提问by Farhad-Taran
I have the following XML file that I need to convert to JSON in the server. Initially I thought I would convert it to a Dictionary and then use the JavaScriptSerializer to turn it into JSON but since each column could have a different value type, I don't think it would work. Has anyone done something similar before in C#/LINQ?
我有以下 XML 文件,需要在服务器中将其转换为 JSON。最初我以为我会将它转换为字典,然后使用 JavaScriptSerializer 将其转换为 JSON,但由于每列可能具有不同的值类型,我认为它行不通。有没有人在 C#/LINQ 中做过类似的事情?
I need to preserve the Value Types(Boolean, String, Integer) of each column.
我需要保留每列的值类型(布尔、字符串、整数)。
I would appreciate any advice on this as Im just starting to work with XML. Thanks.
我将不胜感激,因为我刚刚开始使用 XML。谢谢。
<Columns>
<Column Name="key1" DataType="Boolean">True</Column>
<Column Name="key2" DataType="String">Hello World</Column>
<Column Name="key3" DataType="Integer">999</Column>
</Columns>
采纳答案by Darin Dimitrov
using System;
using System.Linq;
using System.Web.Script.Serialization;
using System.Xml.Linq;
class Program
{
static void Main()
{
var xml =
@"<Columns>
<Column Name=""key1"" DataType=""Boolean"">True</Column>
<Column Name=""key2"" DataType=""String"">Hello World</Column>
<Column Name=""key3"" DataType=""Integer"">999</Column>
</Columns>";
var dic = XDocument
.Parse(xml)
.Descendants("Column")
.ToDictionary(
c => c.Attribute("Name").Value,
c => c.Value
);
var json = new JavaScriptSerializer().Serialize(dic);
Console.WriteLine(json);
}
}
produces:
产生:
{"key1":"True","key2":"Hello World","key3":"999"}
Obviously this treats all the values as strings. If you want to keep the underlying type semantics you could do the following:
显然,这将所有值视为字符串。如果您想保留底层类型语义,您可以执行以下操作:
using System;
using System.Linq;
using System.Web.Script.Serialization;
using System.Xml.Linq;
class Program
{
static void Main()
{
var xml =
@"<Columns>
<Column Name=""key1"" DataType=""System.Boolean"">True</Column>
<Column Name=""key2"" DataType=""System.String"">Hello World</Column>
<Column Name=""key3"" DataType=""System.Int32"">999</Column>
</Columns>";
var dic = XDocument
.Parse(xml)
.Descendants("Column")
.ToDictionary(
c => c.Attribute("Name").Value,
c => Convert.ChangeType(
c.Value,
typeof(string).Assembly.GetType(c.Attribute("DataType").Value, true)
)
);
var json = new JavaScriptSerializer().Serialize(dic);
Console.WriteLine(json);
}
}
produces:
产生:
{"key1":true,"key2":"Hello World","key3":999}
And if you cannot modify the underlying XML structure you will need a custom function that will convert between your custom types and the underlying .NET type:
如果您无法修改底层 XML 结构,您将需要一个自定义函数来在您的自定义类型和底层 .NET 类型之间进行转换:
using System;
using System.Linq;
using System.Web.Script.Serialization;
using System.Xml.Linq;
class Program
{
static void Main()
{
var xml =
@"<Columns>
<Column Name=""key1"" DataType=""Boolean"">True</Column>
<Column Name=""key2"" DataType=""String"">Hello World</Column>
<Column Name=""key3"" DataType=""Integer"">999</Column>
</Columns>";
var dic = XDocument
.Parse(xml)
.Descendants("Column")
.ToDictionary(
c => c.Attribute("Name").Value,
c => Convert.ChangeType(
c.Value,
GetType(c.Attribute("DataType").Value)
)
);
var json = new JavaScriptSerializer().Serialize(dic);
Console.WriteLine(json);
}
private static Type GetType(string type)
{
switch (type)
{
case "Integer":
return typeof(int);
case "String":
return typeof(string);
case "Boolean":
return typeof(bool);
// TODO: add any other types that you want to support
default:
throw new NotSupportedException(
string.Format("The type {0} is not supported", type)
);
}
}
}
回答by oopbase
回答by Termininja
For deep nesting of XML elements with more and unknown attributes you can use this recursion:
对于具有更多和未知属性的 XML 元素的深层嵌套,您可以使用此递归:
private static string XmlToJson(string xmlString)
{
return new JavaScriptSerializer().Serialize(GetXmlValues(XElement.Parse(xmlString)));
}
private static Dictionary<string, object> GetXmlValues(XElement xml)
{
var attr = xml.Attributes().ToDictionary(d => d.Name.LocalName, d => (object)d.Value);
if (xml.HasElements) attr.Add("_value", xml.Elements().Select(e => GetXmlValues(e)));
else if (!xml.IsEmpty) attr.Add("_value", xml.Value);
return new Dictionary<string, object> { { xml.Name.LocalName, attr } };
}
For your example the result will be:
对于您的示例,结果将是:
{
"Columns":{
"_value":[
{
"Column":{
"Name":"key1",
"DataType":"Boolean",
"_value":"True"
}
},
{
"Column":{
"Name":"key2",
"DataType":"String",
"_value":"Hello World"
}
},
{
"Column":{
"Name":"key3",
"DataType":"Integer",
"_value":"999"
}
}
]
}
}
And for more complex XML case like this, you can check the JSON analogue here.

