【问题标题】:Convert single XElement to object将单个 XElement 转换为对象
【发布时间】:2013-09-07 15:04:29
【问题描述】:

我有一个 XElement 看起来像这样:

<row flag="1" sect="" header="" body="" extrainfo="0" />

然后我有一个看起来像这样的类:

public class ProductAttribute
{
    public string Flag { get; set; }
    public string Sect { get; set; }
    public string Header { get; set; }
    public string Body { get; set; }
    public string Extrainfo { get; set; }
}

如何将此XElement 转换为ProductAttribute 对象?

【问题讨论】:

    标签: c# .net xml linq-to-xml xelement


    【解决方案1】:

    你必须在你的类和类成员上放置正确的序列化属性

    [Serializable()]
    [XmlRoot(ElementName = "row")]
    public class ProductAttribute
    {
        [XmlAttribute("flag")]
        public string Flag { get; set; }
        [XmlAttribute("sect")]
        public string Sect { get; set; }
        [XmlAttribute("header")]
        public string Header { get; set; }
        [XmlAttribute("body")]
        public string Body { get; set; }
        [XmlAttribute("extrainfo")]
        public string Extrainfo { get; set; }
    }
    

    【讨论】:

    • 目前为止最好的解决方案,如果可行的话。但我得到:Attribute System.Xml.Serialization.XmlElementAttribute is not valid on this declaration type. It is valid on 'Property,Field,Parameter,ReturnValue' declarations only
    • 但是你没有解释/显示的是从XElement到ABC的实际转换。
    【解决方案2】:

    你可以这样做:

    1) 首先你应该给类赋予属性:

    [XmlRoot("row")]
    public class ProductAttribute
    {
        [XmlAttribute("flag")]
        public string Flag { get; set; }
        [XmlAttribute("sect")]
        public string Sect { get; set; }
        [XmlAttribute("header")]
        public string Header { get; set; }
        [XmlAttribute("body")]
        public string Body { get; set; }
        [XmlAttribute("extrainfo")]
        public string Extrainfo { get; set; }
    }
    

    2) 现在您可以像这样反序列化您的 XElement 或简单的 xml 字符串:

    ProductAttribute productAttribute = new ProductAttribute();
    XElement xElement = XElement.Parse(
    "<row flag='1' sect='3' header='4444' body='3434' extrainfo='0' />");
    
    //StringReader reader = new StringReader(
    //"<row flag='1' sect='3' header='4444' body='3434' extrainfo='0' />");
    
    StringReader reader = new StringReader(xElement.ToString());
    XmlSerializer xmlSerializer = new XmlSerializer(typeof(ProductAttribute));
    productAttribute = (ProductAttribute)xmlSerializer.Deserialize(reader);
    

    希望对你有帮助。

    【讨论】:

      【解决方案3】:

      你试过了吗:

      XElement element = //Your XElement
      var serializer = new XmlSerializer(typeof(ProductAttribute));
      (ProductAttribute)serializer.Deserialize(element.CreateReader()) 
      

      【讨论】:

      • 是的,我试过了,但我只得到:&lt;row xmlns=''&gt; was not expected.
      • 您应该将正确的序列化属性放在 ProductAttribute 类上。就像类的 XmlElement 和每个属性的 XmlAttribute 一样。
      • 谢谢。但是我不允许在课堂上输入[XmlElement("row")]。 Attribute System.Xml.Serialization.XmlElementAttribute is not valid on this declaration type. It is valid on 'Property,Field,Parameter,ReturnValue' declarations only
      • 如果你得到&lt;row xmlns=''&gt; was not expected这里有一个解决方案:stackoverflow.com/a/1557145/3059082
      【解决方案4】:

      我会添加一个接受 XElement 的构造函数。

      public class ProductAttribute
      {
          public string Flag { get; set; }
          public string Sect { get; set; }
          public string Header { get; set; }
          public string Body { get; set; }
          public string Extrainfo { get; set; }
      
          public ProductAttribute(XElement xElement){
              Flag = (string)element.Attribute("flag");
              Sect = (string)element.Attribute("sect").Value;
              Header = (string)element.Attribute("header ").Value;
              Body = (string)element.Attribute("body").Value;
              Extrainfo = (string)element.Attribute("extrainfo").Value;
          }
      }
      

      然后你就可以打电话了

      var productAttribute = new ProductAttribute(element);
      

      如果您想使这种动态化,您可以使用反射获取类上的属性,然后循环并在 XElement 中搜索该属性,然后以相同的方式设置该属性。但是我会保持简单,因为对象并不复杂。

      【讨论】:

        【解决方案5】:

        这看起来相当简单(至少没有错误检查...):

        var res = new ProdicAttribute {
          Flag = (string)element.Attribute("flag"),
          Sect = (string)element.Attribute("sect"),
          ...
        }
        

        【讨论】:

        • 这是手动映射。但是,如果我有一个具有 200 个属性的 XElement 怎么办?我希望 C#/.net 有一个更简单的解决方案
        • 正确获取 XML 序列化属性并非易事(而且我发现它容易出错)......我认为这不再是工作了。此外,它有助于分离关注点:-)。
        【解决方案6】:
        var element = XElement.Parse("<row flag="1" sect="" header="" body="" extrainfo="0" />");
        
        var productAttribute = new ProductAttribute {
            Flag = (string)element.Attribute("flag"),
            Sect = (string)element.Attribute("sect"),
            Header = (string)element.Attribute("header"),
            Body = (string)element.Attribute("body"),
            Extrainfo = (string)element.Attribute("extrainfo")
        };
        

        但我不认为所有ProductAttribute 类属性都应该输入为string。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-07-20
          • 1970-01-01
          • 2019-02-12
          • 1970-01-01
          • 2022-01-15
          • 2011-12-12
          相关资源
          最近更新 更多