将单个 XElement 转换为对象

Posted

技术标签:

【中文标题】将单个 XElement 转换为对象【英文标题】:Convert single XElement to object 【发布时间】: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 对象?

【问题讨论】:

【参考方案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 但是你没有解释/显示的是从XElementABC的实际转换。【参考方案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这里有一个解决方案:***.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

【讨论】:

以上是关于将单个 XElement 转换为对象的主要内容,如果未能解决你的问题,请参考以下文章

将 XElement 转换为 XmlNode

如何将 Dictionary<XElement,XElement> 转换为 xml 文件?

如何将 XElement 转换为 XDocument

将 XElement 的子级转换为字符串 [重复]

ASP.NET MVC4 Web API MediaTypeFormatter 转换器将 XElement 转换为 JSON

Parse 转换 将括号里面的转成Parse前面的类型