我有一个包含两个参数的类。一个是以分钟为单位的更新时间,另一个是以秒为单位的相同值:
using System.Xml.Serialization;
[XmlRoot(ElementName="config")]
public class Config
{
[XmlElement(ElementName = "update_mins")]
public int Minutes
{
get
{
return this.Seconds / 60;
}
set
{
this.Seconds = value * 60;
}
}
[XmlElement(ElementName = "update_secs")]
public int Seconds { get; set; }
}
我得到的xml字符串可以包含update_mins或update_secs,但不能同时包含两者。我需要能够使用这个类来反序列化这些字符串,这没问题。我还需要能够将这些类分类并发送它们,但是当我进行serailzation时它包括update_secs和update_mins。像这样:
<config>
<update_mins>23</update_mins>
<update_secs>1380</update_secs>
</config>
当我想要这个时:
<config>
<update_secs>1380</update_secs>
</config>
我尝试将XmlIgnore放在update_mins值上,但这阻止了它反序列化元素。是否可以这样做,如果是这样的话?
我的完整代码示例是:
namespace Scrap
{
class Program
{
static void Main(string[] args)
{
string s = "<config><update_mins>23</update_mins></config>";
XmlSerializer searializer = new XmlSerializer(typeof(Config));
Config result = (Config)searializer.Deserialize(new StringReader(s));
Console.WriteLine("Minutes: " + result.Minutes);
Console.WriteLine("Seconds: " + result.Seconds);
Debug.Assert(result.Minutes == 23);
Debug.Assert(result.Seconds == 1380);
StringWriter s2w = new StringWriter();
searializer.Serialize(s2w, result);
Console.WriteLine(s2w.ToString());
string xmlResult = "<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n" +
"<config xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n" +
" <update_secs>1380</update_secs>\r\n" +
"</config>";
Debug.Assert(s2w.ToString() == xmlResult);
Console.ReadKey(true);
}
}
[XmlRoot(ElementName = "config")]
public class Config
{
[XmlElement(ElementName = "update_mins")]
public int Minutes
{
get
{
return this.Seconds / 60;
}
set
{
this.Seconds = value * 60;
}
}
[XmlElement(ElementName = "update_secs")]
public int Seconds { get; set; }
}
}
答案 0 :(得分:0)
我会在[XmlIgnore]
上使用Minutes
,因为它是
您提到您无法控制哪个元素被填充,它可能是其中之一或两者。
一种可能的解决方案是添加一层抽象。
SecondsXml
和MinutesXml
,让他们读取XML值(在其上定义属性)Minutes
和Seconds
_isLoaded
Minutes
或Seconds
时,请检查_isLoaded
,如果为false,则检查SecondsXml
和MinutesXml
中的值,以确定哪个已加载相应地设置Minutes
和Seconds
。如果您不希望SecondsXml
和MinutesXml
公开,请将其定义为私有,但使用DataContractSerializer进行反序列化。
答案 1 :(得分:0)
尝试
class Config : IDeserializationCallback
{
void IDeserializationCallback.OnDeserialization(object sender)
{
}
}
或
class Config
{
[OnDeserializing]
void OnDeserialization(StreamingContext context)
{
}
}
答案 2 :(得分:0)
这仍然不是一个理想的解决方案,但我解决这个问题的方法是将[XmlIgnore]添加到Minutes属性(正如Aliostad和其他人所建议的那样),然后像这样添加AllElements属性:
[XmlAnyElement]
public XmlElement[] AllElements
{
get
{
XmlElement[] value = new XmlElement[0];
return value;
}
set
{
if (value != null)
{
foreach (XmlElement e in value)
{
switch (e.Name)
{
case "update_mins":
this.Minutes = Convert.ToInt32(e.InnerText);
break;
}
}
}
}
}