如何反序列化元素名称列表编号的XML?
问题描述:
大家好消息! 我遇到了一些棘手的XML新问题。如何反序列化元素名称列表编号的XML?
<?xml version="1.0" encoding="UTF-8"?>
<response>
<osmp_txn_id>100500</osmp_txn_id>
<result>0</result>
<fields>
<field1 name="name">Ko Chu Bey</field1>
<field2 name="contract">777-1</field2>
...
<fieldN name="account">65000</fieldN>
</fields>
<comment>Result for round 1 of fight vs Pe Re Svet: 1:1</comment>
</response>
我的问题是,内置的实用工具,生成XSD的ANS CS的使不同类各fieldX
。而且因为它们的数量可能会很多,所以它变成了一个非常亲密的地方。 有没有办法将对象从这个XML反序列化成一个具有field
对象数组的类?
答
如果你有一个字符串,你可以做到这一点使用LINQ to XML和名称的正则表达式的XML:
var fieldElementNameRegex = new Regex(
"^field[0-9]+$",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
var xml = XElement.Parse(xmlString);
var fieldElements = xml
.Descendants()
.Where(e => fieldElementNameRegex.IsMatch(e.Name.ToString()))
.ToArray();
答
最好的解决办法是让自己的IXmlSerializable
实施使用XML有问题。预先做好会很麻烦,但从长远来看,这可能是值得的。
作为一种替代方法(我不会推荐它太强烈),您可以写一些小技巧来反思默认序列化对象的属性 - 您解释的属性是由内置实用程序生成的。
例如,假设:
公共类字段 { 公共字符串名称; 公共字符串值; }
public class response
{
public Field field1;
public Field field2;
public Field field3;
public Field field4;
public Field field5;
public Field field6;
public Field field7;
public string comments;
public string osmp_txn_id;
public string result;
}
可以定义下面的 “方便” 类:
public class myResponse
{
public string comments;
public string osmp_txn_id;
public string result;
public List<Field> fields;
}
,这将是如何填充更方便类:
myResponse ConvertFromResult(response target)
{
var returnObject = new myResponse();
var fields = target.GetType().GetFields().Where(f => f.FieldType == typeof(Field));
returnObject.fields = (from f in fields
let fp = f.GetValue(target) as Field
where fp != null
select fp).ToList();
returnObject.comments = target.comments;
returnObject.osmp_txn_id = target.osmp_txn_id;
returnObject.result = target.result;
return returnObject;
}
这都是概念性的,所以你可能需要从这里“推出自己的”解决方案。另一种方法是使用扩展方法为xml反序列化对象返回一个IEnumerable<field>
,如果要以非性能密集型方式使用它,这将是可行的。
public static class responseExtensions
{
private static IEnumerable<Field> GetFields(this response target)
{
var fields = target.GetType().GetFields().Where(f => f.FieldType == typeof(Field));
return from f in fields
let fp = f.GetValue(target) as Field
where fp != null
select fp;
}
}
您需要完全控制反序列化过程;看起来像这些字段可以创建一个不错的KeyValuePair。在我的手机上,现在无法真正给出答案,但我会研究如何实现ISerializable。 – 2013-04-09 12:09:03