Rad*_*adu 51 .net xml serialization anonymous-types
我知道匿名类型被编译器标记为私有,属性是只读的.有没有办法将它们序列化为xml(没有反序列化)?它适用于JSON,我如何使用XML?
Mat*_*ted 68
这样的事情应该让你开始......
class Program
{
static void Main(string[] args)
{
var me = new
{
Hello = "World",
Other = new
{
My = "Object",
V = 1,
B = (byte)2
}
};
var x = me.ToXml();
}
}
public static class Tools
{
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
public static bool IsSimpleType(this Type type)
{
return type.IsPrimitive || WriteTypes.Contains(type);
}
public static XElement ToXml(this object input)
{
return input.ToXml(null);
}
public static XElement ToXml(this object input, string element)
{
if (input == null)
return null;
if (string.IsNullOrEmpty(element))
element = "object";
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null)
{
var type = input.GetType();
var props = type.GetProperties();
var elements = from prop in props
let name = XmlConvert.EncodeName(prop.Name)
let val = prop.GetValue(input, null)
let value = prop.PropertyType.IsSimpleType()
? new XElement(name, val)
: val.ToXml(name)
where value != null
select value;
ret.Add(elements);
}
return ret;
}
}
Run Code Online (Sandbox Code Playgroud)
...结果xml ...
<object>
<Hello>World</Hello>
<Other>
<My>Object</My>
<V>1</V>
<B>2</B>
</Other>
</object>
Run Code Online (Sandbox Code Playgroud)
ric*_*rdo 24
谢谢你,出色的工作@Matthew和@Martin.
我做了一些修改来容纳Nullables和Enums.我也改变了它,以便根据属性+索引的名称命名数组元素.
如果有人有兴趣,这是代码
public static class ObjectExtensions {
#region Private Fields
private static readonly Type[] WriteTypes = new[] {
typeof(string), typeof(DateTime), typeof(Enum),
typeof(decimal), typeof(Guid),
};
#endregion Private Fields
#region .ToXml
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement ToXml(this object input) {
return input.ToXml(null);
}
/// <summary>
/// Converts an anonymous type to an XElement.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="element">The element name.</param>
/// <returns>Returns the object as it's XML representation in an XElement.</returns>
public static XElement ToXml(this object input, string element) {
return _ToXml(input, element);
}
private static XElement _ToXml(object input, string element, int? arrayIndex = null, string arrayName = null) {
if (input == null)
return null;
if (String.IsNullOrEmpty(element)) {
string name = input.GetType().Name;
element = name.Contains("AnonymousType")
? "Object"
: arrayIndex != null
? arrayName + "_" + arrayIndex
: name;
}
element = XmlConvert.EncodeName(element);
var ret = new XElement(element);
if (input != null) {
var type = input.GetType();
var props = type.GetProperties();
var elements = props.Select(p => {
var pType = Nullable.GetUnderlyingType(p.PropertyType) ?? p.PropertyType;
var name = XmlConvert.EncodeName(p.Name);
var val = pType.IsArray ? "array" : p.GetValue(input, null);
var value = pType.IsArray
? GetArrayElement(p, (Array)p.GetValue(input, null))
: pType.IsSimpleType() || pType.IsEnum
? new XElement(name, val)
: val.ToXml(name);
return value;
})
.Where(v=>v !=null);
ret.Add(elements);
}
return ret;
}
#region helpers
/// <summary>
/// Gets the array element.
/// </summary>
/// <param name="info">The property info.</param>
/// <param name="input">The input object.</param>
/// <returns>Returns an XElement with the array collection as child elements.</returns>
private static XElement GetArrayElement(PropertyInfo info, Array input) {
var name = XmlConvert.EncodeName(info.Name);
XElement rootElement = new XElement(name);
var arrayCount = input == null ? 0 : input.GetLength(0);
for (int i = 0; i < arrayCount; i++) {
var val = input.GetValue(i);
XElement childElement = val.GetType().IsSimpleType() ? new XElement(name + "_" + i, val) : _ToXml(val, null, i, name);
rootElement.Add(childElement);
}
return rootElement;
}
#region .IsSimpleType
public static bool IsSimpleType(this Type type) {
return type.IsPrimitive || WriteTypes.Contains(type);
}
#endregion .IsSimpleType
#endregion helpers
#endregion .ToXml
}
Run Code Online (Sandbox Code Playgroud)
我知道这是一篇旧帖子,但我的解决方案仅用2 行代码将匿名类型转换为 XML 。
首先将您的匿名类型转换为 JSON,然后从 JSON 转换为 XML。
var jsonText = JsonConvert.SerializeObject(data); // convert to JSON
XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonText); // convert JSON to XML Document
Run Code Online (Sandbox Code Playgroud)
样本
var data = new // data - Anonymous Type
{
Request = new
{
OrderNumber = 123,
Note = "Hello World"
}
};
var jsonText = JsonConvert.SerializeObject(data);
XmlDocument doc = JsonConvert.DeserializeXmlNode(jsonText);
Console.WriteLine(doc.OuterXml);
Run Code Online (Sandbox Code Playgroud)
输出
<Request>
<OrderNumber>123</OrderNumber>
<Note>Hello World</Note>
</Request>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20185 次 |
| 最近记录: |