我想反序列化以下XML元素。
<error code="1" type="post">
<bad-request xmlns="blah:ns"> // <-- may be some different element name
<text>You fail.</text> // <-- this is optional
</bad-request>
</error>子元素bad-request可以有几个不同的名称。我想将该元素名称反序列化为一个错误类型,该类型在我的命名空间中定义为枚举,如下所示。
public enum ErrorType { BadRequest = 1, Forbidden = 2, Blah = 3, ... }此外,我希望将text的元素文本解析为ErrorText属性。所以我的最后一堂课会是这样的。
public class Error
{
public string ErrorText { get; set; }
public ErrorType ErrorType { get; set; }
}如何在C#和反序列化中实现这样的功能?
更新
对我来说,我目前的解决方案似乎有些过火。
public class Error
{
private string _type;
[XmlAttribute("type")]
public string Type // <-- there is clearly a bug in here I should not do that on the type attribute because it has nothing to do with the error type
{
get { return _type; }
set
{
_type = value;
switch (value)
{
case "bad-request":
ErrorType = ErrorTypes.BadRequest;
ErrorText = BadRequest.Text.Value;
break;
default:
...
break;
}
}
}
public ErrorTypes ErrorType { get; set; }
public string ErrorText { get; set; }
[XmlElement("bad-request")]
public BadRequest BadRequest { get; set; }
}
public enum ErrorTypes
{
BadRequest = 0,
Conflict = 1,
FeatureNotImplemented = 2,
Forbidden = 3
}
public class Text
{
[XmlText]
public string Value { get; set; }
}
public class BadRequest
{
[XmlElement("text")]
public Text Text { get; set; }
}上面的代码要求每个元素名称/类型都有一个单独的类。
发布于 2013-08-30 09:07:48
您可以使用继承来反序列化这种XML,而不是隐藏在enum后面。
public enum ErrorType { BadRequest = 1, Forbidden = 2, Blah = 3, ... }
[Serializable]
[XmlRoot(ElementName="error")]
public class Error
{
[XmlElement(
ElementName = "bad-request",
Type = typeof(BadRequest),
Namespace = "blah:ns")]
[XmlElement(
ElementName = "forbidden",
Type = typeof(Forbidden),
Namespace = "blah:ns")]
public ErrorDetails ErrorDetails { get; set; }
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "code")]
public int Code { get; set; }
}
[Serializable]
public abstract class ErrorDetails
{
public abstract ErrorType ErrorType { get; }
}
[Serializable]
public class BadRequest : ErrorDetails
{
public override ErrorType ErrorType
{
get
{
return ErrorType.BadRequest;
}
}
[XmlElement(ElementName = "text")]
public string Text { get; set; }
public override string ToString()
{
return Text;
}
}
[Serializable]
public class Forbidden : ErrorDetails
{
public override ErrorType ErrorType
{
get
{
return ErrorType.Forbidden;
}
}
[XmlElement(ElementName = "text")]
public string Text { get; set; }
public override string ToString()
{
return Text;
}
}测试:
string data1 = @"<error code=""1"" type=""post"">
<bad-request xmlns=""blah:ns"">
<text>You fail.</text>
</bad-request>
</error>";
string data2 = @"<error code=""1"" type=""post"">
<forbidden xmlns=""blah:ns"">
<text>You fail.</text>
</forbidden>
</error>";
byte[] bytes1 = ASCIIEncoding.ASCII.GetBytes(data1);
byte[] bytes2 = ASCIIEncoding.ASCII.GetBytes(data2);
MemoryStream ms1 = new MemoryStream(bytes1);
MemoryStream ms2 = new MemoryStream(bytes2);
XmlSerializer xs = new XmlSerializer(typeof(Error));
Error result1 = xs.Deserialize(ms1) as Error;
Error result2 = xs.Deserialize(ms2) as Error;
Console.WriteLine(result1.ErrorDetails.ToString());
Console.WriteLine(result2.ErrorDetails.ToString());https://stackoverflow.com/questions/18521175
复制相似问题