首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中将不同的元素类型反序列化为一个对象属性?

在C#中将不同的元素类型反序列化为一个对象属性?
EN

Stack Overflow用户
提问于 2013-08-29 21:22:04
回答 1查看 1.8K关注 0票数 1

我想反序列化以下XML元素。

代码语言:javascript
复制
<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可以有几个不同的名称。我想将该元素名称反序列化为一个错误类型,该类型在我的命名空间中定义为枚举,如下所示。

代码语言:javascript
复制
public enum ErrorType { BadRequest = 1, Forbidden = 2, Blah = 3, ... }

此外,我希望将text的元素文本解析为ErrorText属性。所以我的最后一堂课会是这样的。

代码语言:javascript
复制
public class Error 
{
  public string ErrorText { get; set; }
  public ErrorType ErrorType { get; set; }
}

如何在C#和反序列化中实现这样的功能?

更新

对我来说,我目前的解决方案似乎有些过火。

代码语言:javascript
复制
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; }
}

上面的代码要求每个元素名称/类型都有一个单独的类。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-30 09:07:48

您可以使用继承来反序列化这种XML,而不是隐藏在enum后面。

代码语言:javascript
复制
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;
    }
}

测试:

代码语言:javascript
复制
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());
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18521175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档