我正在处理一个返回单个XML块的项目,如下所示:
<root>
<x_val />
<x_val2 />
<x_addr1 />
<x_addr2 />
<x_city />
<x_state />
<x_country />
<x_zip />
</root>
在这个项目中,我可以进行多次返回各种信息的调用,但大部分都会在底部包含地址信息。
编写C#类时,我不想在我创建的每个响应对象中为每个节点创建属性。相反,我更喜欢定义一个Address对象,以便这样使用:
[XmlRoot("root")]
[Serializable]
public class ReturnItem1
{
[XmlElement("x_val")]
public string FirstValue{ get; set; }
[XmlElement("x_val2")]
public string SecondValue{ get; set; }
public Address AddressInfo { get; set; }
public ReturnItem1()
{
AddressInfo = new Address();
}
}
public class Address
{
[XmlElement("x_addr1")]
public string Address1 { get; set; }
[XmlElement("x_addr2")]
public string Address2 { get; set; }
[XmlElement("x_city")]
public string City { get; set; }
[XmlElement("x_state")]
public string State { get; set; }
[XmlElement("x_country")]
public string Country { get; set; }
[XmlElement("x_zip")]
public string PostalCode { get; set; }
}
反序列化时,我执行以下逻辑(响应类型为XElement):
var serializer = new XmlSerializer(typeof(ReturnItem1));
var returnObject = (ReturnItem1)serializer.Deserialize(response.CreateReader());
FirstValue和SecondValue的值填充在returnObject中,但Address中的属性始终为null。
我尝试将[XmlRoot(&#34; root)&#34;]属性添加到Address类中,但这并不起作用。也没有将ReturnItem1中Address属性的XmlElement属性设置为&#34; root&#34;或任何其他节点名称。
有没有办法使用这种方法将单个XML节点反序列化为具有一个或多个子对象的对象?
答案 0 :(得分:0)
尝试使用与XML元素匹配的私有成员和封装它们的公共地址属性。见这个例子:
答案 1 :(得分:0)
我已经设法使用TAMTAM的建议将XML反序列化为对象,如下所示:
[DataContract(Name="root", Namespace = "")]
public class ReturnItem1
{
[DataMember(Name = "x_val", Order = 0)]
public string FirstValue { get; set; }
[DataMember(Name = "x_val2", Order = 1)]
public string SecondValue { get; set; }
[DataMember(Name = "x_addr1", Order = 2)]
private string _address;
[DataMember(Name = "x_addr2", Order = 3)]
private string _address2;
[DataMember(Name = "x_city", Order = 4)]
private string _city;
[DataMember(Name = "x_state", Order = 5)]
private string _state;
[DataMember(Name = "x_country", Order = 6)]
private string _country;
[DataMember(Name = "x_zip", Order = 7)]
private string _postalCode;
public Address AddressInfo { get; set; }
[OnDeserialized()]
void OnDeserialized(StreamingContext context)
{
AddressInfo = new Address
{
Address1 = _address,
Address2 = _address2,
PostalCode = _postalCode,
City = _city,
Country = _country,
State = _state
};
}
}
我终于找到了一个可以忍受的解决方案。 ReturnItem1扩展了一个包含List of AdditionalAttributesToDeserialize的基类。然后在ReturnItem1的OnDeserialized方法中,我添加&#34; AddressInfo&#34;到那个清单。在反序列化基础对象之后,我迭代遍历该列表,使用Reflection查找属性和属性的类型,并且对于每个条目,程序创建新的DataContractSerializer并在使用Reflection设置属性之前反序列化属性&# 39; s对新反序列化对象的值。它是一种蛮力方法,在将属性名称添加到AdditionalPropertiesToDeserialize列表时很容易指责属性名称,但它允许我在一个地方定义我的对象和属性并随意重用它们。