无法正确反序列化 xml
Can't deserialize xml properly
我要反序列化以下字符串:
<result>
<error>
<errorcode>0</errorcode>
<errorge>წარმატებით</errorge>
<errorru>Удачно</errorru>
<erroren>successfully</erroren>
<line>89</line>
</error>
<amount>
<gel>1</gel>
</amount>
<user>01001</user>
<service>MyService</service> // here
<data>
<nickname>popcorn2</nickname>
<identification_name>identified</identification_name>
<wallet_code>5554654</wallet_code>
<NationalRate>1</NationalRate>
<RATE>1</RATE>
<GENERATED_AMOUNT>1</GENERATED_AMOUNT>
<CURRENCY>GEL</CURRENCY>
</data>
<accoutant>
<agentBenefit>0</agentBenefit>
<agentCommission>0.44</agentCommission>
<clientCommission>0</clientCommission>
</accoutant>
<service>
<min_amount>0.49</min_amount>
<max_amount>1500.00</max_amount>
<currency>GEL</currency>
</service>
<avance>-134206.1500</avance>
<operation_status>0</operation_status>
</result>
如您所见,它有两个名为 "service" 的标签,它们具有不同的内容
这是我一直在使用的 class
[XmlRoot(ElementName = "error")]
public class ErrorInfo
{
[XmlElement(ElementName = "errorcode")]
public string Errorcode { get; set; }
[XmlElement(ElementName = "errorge")]
public string Errorge { get; set; }
[XmlElement(ElementName = "errorru")]
public string Errorru { get; set; }
[XmlElement(ElementName = "erroren")]
public string Erroren { get; set; }
[XmlElement(ElementName = "line")]
public string Line { get; set; }
}
[XmlRoot(ElementName = "amount")]
public class Amount
{
[XmlElement(ElementName = "gel")]
public string Gel { get; set; }
}
[XmlRoot(ElementName = "data")]
public class Data
{
[XmlElement(ElementName = "nickname")]
public string Nickname { get; set; }
[XmlElement(ElementName = "identification_name")]
public string Identification_name { get; set; }
[XmlElement(ElementName = "wallet_code")]
public string Wallet_code { get; set; }
[XmlElement(ElementName = "NationalRate")]
public string NationalRate { get; set; }
[XmlElement(ElementName = "RATE")]
public string RATE { get; set; }
[XmlElement(ElementName = "GENERATED_AMOUNT")]
public string GENERATED_AMOUNT { get; set; }
[XmlElement(ElementName = "CURRENCY")]
public string CURRENCY { get; set; }
}
[XmlRoot(ElementName = "accoutant")]
public class Accoutant
{
[XmlElement(ElementName = "agentBenefit")]
public string AgentBenefit { get; set; }
[XmlElement(ElementName = "agentCommission")]
public string AgentCommission { get; set; }
[XmlElement(ElementName = "clientCommission")]
public string ClientCommission { get; set; }
}
[XmlRoot(ElementName = "service")]
public class Service
{
[XmlElement(ElementName = "min_amount")]
public string Min_amount { get; set; }
[XmlElement(ElementName = "max_amount")]
public string Max_amount { get; set; }
[XmlElement(ElementName = "currency")]
public string Currency { get; set; }
}
[XmlRoot(ElementName = "result")]
public class Result
{
[XmlElement(ElementName = "error")]
public ErrorInfo Error { get; set; }
[XmlElement(ElementName = "amount")]
public Amount Amount { get; set; }
[XmlElement(ElementName = "user")]
public string User { get; set; }
[XmlElement(ElementName = "data")]
public Data Data { get; set; }
[XmlElement(ElementName = "accoutant")]
public Accoutant Accoutant { get; set; }
[XmlElement(ElementName = "service")]
public Service[] Service { get; set; }
[XmlElement(ElementName = "avance")]
public string Avance { get; set; }
[XmlElement(ElementName = "operation_status")]
public string Operation_status { get; set; }
}
我尝试将服务标签作为数组处理,但无法正常工作。我能够从最后一个标签中获取值,但不能从第一个标签中获取值。这两个标签都是必需的,所以我想知道是否有办法从这两个标签中获取值?
不能有两个同名的不同元素。它不知道哪个标签属于哪里,您必须将名称更改为 "MyServiceName" 或类似的名称。
Visual Studio 有这个非常棒的功能,您可以将 XML 放入剪贴板,然后执行编辑 -> 选择性粘贴 -> 将 XML 粘贴为 class es.
如果您使用 XML 执行此操作,它会为服务标签生成以下 class:
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class resultService
{
private decimal min_amountField;
private decimal max_amountField;
private string currencyField;
private string[] textField;
/// <remarks/>
public decimal min_amount
{
get
{
return this.min_amountField;
}
set
{
this.min_amountField = value;
}
}
/// <remarks/>
public decimal max_amount
{
get
{
return this.max_amountField;
}
set
{
this.max_amountField = value;
}
}
/// <remarks/>
public string currency
{
get
{
return this.currencyField;
}
set
{
this.currencyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string[] Text
{
get
{
return this.textField;
}
set
{
this.textField = value;
}
}
}
如果你想手动完成,秘诀似乎是添加一个带有 XmlTextAttribute
属性的字段。
按如下方式更改您的 classes:
[XmlRoot(ElementName = "result")]
public class Result
{
// no need XmlElement attribute
public ServiceComplex ServiceComplex { get; set; }
// no need XmlElement attribute
public string ServiceSimple { get; set; }
// other properties
}
// no need XmlRoot attribute
public class ServiceComplex
{
[XmlElement(ElementName = "min_amount")]
public string Min_amount { get; set; }
[XmlElement(ElementName = "max_amount")]
public string Max_amount { get; set; }
[XmlElement(ElementName = "currency")]
public string Currency { get; set; }
}
而不是 ServiceComplex
和 ServiceSimple
,选择适合您的名称。
订阅 XmlSerializer
到 UnknownElement
事件:
var xs = new XmlSerializer(typeof(Result));
xs.UnknownElement += Xs_UnknownElement;
private static void Xs_UnknownElement(object sender, XmlElementEventArgs e)
{
if (e.Element.Name == "service")
{
var result = (Result)e.ObjectBeingDeserialized;
if (e.Element.ChildNodes.Count == 1)
{
result.ServiceSimple = e.Element.InnerText;
}
else
{
result.ServiceComplex = new ServiceComplex
{
Min_amount = e.Element.SelectSingleNode("min_amount").InnerText,
Max_amount = e.Element.SelectSingleNode("max_amount").InnerText,
Currency = e.Element.SelectSingleNode("currency").InnerText
};
}
}
}
在事件处理程序中,我们从 xml.
手动填充 class 的属性
我要反序列化以下字符串:
<result>
<error>
<errorcode>0</errorcode>
<errorge>წარმატებით</errorge>
<errorru>Удачно</errorru>
<erroren>successfully</erroren>
<line>89</line>
</error>
<amount>
<gel>1</gel>
</amount>
<user>01001</user>
<service>MyService</service> // here
<data>
<nickname>popcorn2</nickname>
<identification_name>identified</identification_name>
<wallet_code>5554654</wallet_code>
<NationalRate>1</NationalRate>
<RATE>1</RATE>
<GENERATED_AMOUNT>1</GENERATED_AMOUNT>
<CURRENCY>GEL</CURRENCY>
</data>
<accoutant>
<agentBenefit>0</agentBenefit>
<agentCommission>0.44</agentCommission>
<clientCommission>0</clientCommission>
</accoutant>
<service>
<min_amount>0.49</min_amount>
<max_amount>1500.00</max_amount>
<currency>GEL</currency>
</service>
<avance>-134206.1500</avance>
<operation_status>0</operation_status>
</result>
如您所见,它有两个名为 "service" 的标签,它们具有不同的内容
这是我一直在使用的 class
[XmlRoot(ElementName = "error")]
public class ErrorInfo
{
[XmlElement(ElementName = "errorcode")]
public string Errorcode { get; set; }
[XmlElement(ElementName = "errorge")]
public string Errorge { get; set; }
[XmlElement(ElementName = "errorru")]
public string Errorru { get; set; }
[XmlElement(ElementName = "erroren")]
public string Erroren { get; set; }
[XmlElement(ElementName = "line")]
public string Line { get; set; }
}
[XmlRoot(ElementName = "amount")]
public class Amount
{
[XmlElement(ElementName = "gel")]
public string Gel { get; set; }
}
[XmlRoot(ElementName = "data")]
public class Data
{
[XmlElement(ElementName = "nickname")]
public string Nickname { get; set; }
[XmlElement(ElementName = "identification_name")]
public string Identification_name { get; set; }
[XmlElement(ElementName = "wallet_code")]
public string Wallet_code { get; set; }
[XmlElement(ElementName = "NationalRate")]
public string NationalRate { get; set; }
[XmlElement(ElementName = "RATE")]
public string RATE { get; set; }
[XmlElement(ElementName = "GENERATED_AMOUNT")]
public string GENERATED_AMOUNT { get; set; }
[XmlElement(ElementName = "CURRENCY")]
public string CURRENCY { get; set; }
}
[XmlRoot(ElementName = "accoutant")]
public class Accoutant
{
[XmlElement(ElementName = "agentBenefit")]
public string AgentBenefit { get; set; }
[XmlElement(ElementName = "agentCommission")]
public string AgentCommission { get; set; }
[XmlElement(ElementName = "clientCommission")]
public string ClientCommission { get; set; }
}
[XmlRoot(ElementName = "service")]
public class Service
{
[XmlElement(ElementName = "min_amount")]
public string Min_amount { get; set; }
[XmlElement(ElementName = "max_amount")]
public string Max_amount { get; set; }
[XmlElement(ElementName = "currency")]
public string Currency { get; set; }
}
[XmlRoot(ElementName = "result")]
public class Result
{
[XmlElement(ElementName = "error")]
public ErrorInfo Error { get; set; }
[XmlElement(ElementName = "amount")]
public Amount Amount { get; set; }
[XmlElement(ElementName = "user")]
public string User { get; set; }
[XmlElement(ElementName = "data")]
public Data Data { get; set; }
[XmlElement(ElementName = "accoutant")]
public Accoutant Accoutant { get; set; }
[XmlElement(ElementName = "service")]
public Service[] Service { get; set; }
[XmlElement(ElementName = "avance")]
public string Avance { get; set; }
[XmlElement(ElementName = "operation_status")]
public string Operation_status { get; set; }
}
我尝试将服务标签作为数组处理,但无法正常工作。我能够从最后一个标签中获取值,但不能从第一个标签中获取值。这两个标签都是必需的,所以我想知道是否有办法从这两个标签中获取值?
不能有两个同名的不同元素。它不知道哪个标签属于哪里,您必须将名称更改为 "MyServiceName" 或类似的名称。
Visual Studio 有这个非常棒的功能,您可以将 XML 放入剪贴板,然后执行编辑 -> 选择性粘贴 -> 将 XML 粘贴为 class es.
如果您使用 XML 执行此操作,它会为服务标签生成以下 class:
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class resultService
{
private decimal min_amountField;
private decimal max_amountField;
private string currencyField;
private string[] textField;
/// <remarks/>
public decimal min_amount
{
get
{
return this.min_amountField;
}
set
{
this.min_amountField = value;
}
}
/// <remarks/>
public decimal max_amount
{
get
{
return this.max_amountField;
}
set
{
this.max_amountField = value;
}
}
/// <remarks/>
public string currency
{
get
{
return this.currencyField;
}
set
{
this.currencyField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTextAttribute()]
public string[] Text
{
get
{
return this.textField;
}
set
{
this.textField = value;
}
}
}
如果你想手动完成,秘诀似乎是添加一个带有 XmlTextAttribute
属性的字段。
按如下方式更改您的 classes:
[XmlRoot(ElementName = "result")]
public class Result
{
// no need XmlElement attribute
public ServiceComplex ServiceComplex { get; set; }
// no need XmlElement attribute
public string ServiceSimple { get; set; }
// other properties
}
// no need XmlRoot attribute
public class ServiceComplex
{
[XmlElement(ElementName = "min_amount")]
public string Min_amount { get; set; }
[XmlElement(ElementName = "max_amount")]
public string Max_amount { get; set; }
[XmlElement(ElementName = "currency")]
public string Currency { get; set; }
}
而不是 ServiceComplex
和 ServiceSimple
,选择适合您的名称。
订阅 XmlSerializer
到 UnknownElement
事件:
var xs = new XmlSerializer(typeof(Result));
xs.UnknownElement += Xs_UnknownElement;
private static void Xs_UnknownElement(object sender, XmlElementEventArgs e)
{
if (e.Element.Name == "service")
{
var result = (Result)e.ObjectBeingDeserialized;
if (e.Element.ChildNodes.Count == 1)
{
result.ServiceSimple = e.Element.InnerText;
}
else
{
result.ServiceComplex = new ServiceComplex
{
Min_amount = e.Element.SelectSingleNode("min_amount").InnerText,
Max_amount = e.Element.SelectSingleNode("max_amount").InnerText,
Currency = e.Element.SelectSingleNode("currency").InnerText
};
}
}
}
在事件处理程序中,我们从 xml.
手动填充 class 的属性