通用XML到对象的映射
本文关键字:映射 对象 XML 通用 | 更新日期: 2023-09-27 18:19:03
我收到一条xml消息,把它翻译成另一种格式,然后发送出去。消息的范围从大约40行到600行或更多行,平均在100行左右。我可以一秒钟收到多条消息,但在繁忙的时候,平均每分钟收到15到20条消息。
由于xml为现有的应用程序提供了新的信息,所以我创建了一个类来模拟输出xml的结构。该对象将创建输出xml,只包括已更改的项,并将输入术语翻译成消费应用程序能够理解的语言。我很难弄清楚的是如何轻松地将传入的xml映射到对象。
传入的xml使用几个不同的模板来确定每个节点的格式。我正在尝试创建一个映射,它可以确定如果节点命名为n,那么它需要转到对象m。下面是我正在尝试做的一个简化示例。消息1<Incoming>
<Name>Bob</Name>
<City>Seattle</City>
<Hobby>Fishing</Hobby>
</Incoming>
消息2 <Incoming>
<Name>Bob</Name>
<Employment>
<JobTitle>Sales</JobTitle>
<Manager>Jessica</Manager>
</Employment>
<Hobby>Reading</Hobby>
</Incoming>
这将进入一个类似于这样的对象:
public Customer
{
public String Name{get; set;}
public Address CustomerAddress{get;set;}
public Employer CustomerEmployer{get;set;}
public List<String> Hobbies{get;set;}
}
public Address
{
public String StreetAddress{get;set;}
public String City{get;set;}
public String State{get;set;}
public String Zip{get;set;}
}
public Employer
{
public String Company{get;set;}
public String Position{get;set;}
public String Manager{get;set;}
public Address CompanyAddress{get;set;}
}
不创建一个长开关情况下,有人有关于如何最好地从xml到对象获取信息的想法吗?由于信息量大,我对处理的时间成本有了更多的意识。
我想过要做一个映射;就像
<Name>Customer:Name</Name>
<City>Customer:Address:City</City>
然而,有一个问题是如何映射列表中的项目,比如Hobby。还有一个问题是如何快速地使用映射。我能想到的唯一方法是让每个对象处理地图的一部分来确定路径,尽管这听起来很昂贵。
我不太担心不同级别的重复地址。这个数据是一个例子。在我实际的xml中,我不认为我有任何重复。
我感谢大家的任何帮助或建议。我能够使用映射来使用反射和递归访问属性。我这样设置映射路径:
map = new Dictionary<string, string>();
map.Add("Name", "Name");
map.Add("Street", "Address.Address");
map.Add("City", "Address.City");
map.Add("State", "Address.State");
map.Add("Zip", "Address.Zip");
map.Add("Activity", "*Hobbies.Hobby");
map.Add("Years", "*Hobbies.Years");
星号表示这是一个列表,需要一个键。我在处理中添加了关键字,所以我发送的完整路径类似于"* hiking .嗜好。"年",徒步旅行是关键。处理它的方法如下:
private void SetValue(object source, String path, String value)
{
if (path.Contains('.'))
{
// If this is not the ending Property, continue recursing
int index = path.IndexOf('.');
String property = path.Substring(0, index);
object nextSource;
if(property.Contains("*"))
{
path = path.Substring(index + 1);
index = path.IndexOf('.');
String dictionaryName = path.Substring(0, index);
property = property.Substring(1);
IDictionary list = source.GetType().GetProperty(dictionaryName).GetValue(source, null) as IDictionary;
if (!list.Contains(property))
{
Type[] arguments = list.GetType().GetGenericArguments();
list.Add(property, Activator.CreateInstance(arguments[1]));
}
nextSource = list[property];
}
else
nextSource = source.GetType().GetProperty(property).GetValue(source, null);
SetValue(nextSource, path.Substring(index + 1), value);
}
else
{
PropertyInfo pi = source.GetType().GetProperty(path);
pi.SetValue(source, Convert.ChangeType(value, pi.PropertyType), null);
}
}