将单个XElement转换为对象。

18

我有一个单独的 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对象?

6个回答

19

你需要在你的类和类成员上放置正确的序列化属性。

[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; }
}

1
目前最佳解决方案,如果它能够工作的话。但是我得到了以下错误信息: “Attribute System.Xml.Serialization.XmlElementAttribute is not valid on this declaration type. It is valid on 'Property,Field,Parameter,ReturnValue' declarations only” - Numm3n
2
但是你没有解释/展示的是从XElementABC的实际转换。 - Andrew Truckle

14
你可以这样做:
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);

希望它能对您有所帮助。


10

您尝试过以下方法吗:

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

是的,我已经尝试过了,但我只得到了这个错误:<row xmlns=''> was not expected。 - Numm3n
你应该在ProductAttribute类上放置正确的序列化属性,例如XmlElement用于类,XmlAttribute用于每个属性。 - Alberto
谢谢,但我不能在类上放置 [XmlElement("row")]Attribute System.Xml.Serialization.XmlElementAttribute 在此声明类型上无效。它只对“属性、字段、参数和返回值”声明有效。 - Numm3n
如果你遇到了 <row xmlns=''> was not expected 的问题,可以在这里找到解决方案:https://dev59.com/7uo6XIcBkEYKwwoYTzEw#1557145 - Wildcat Matt

3
我建议添加一个构造函数,该函数接受一个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,然后以类似的方式设置该属性。但是我会保持简单,因为对象不复杂。

2

这似乎相当简单(至少没有错误检查...):

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

1
这是手动映射。但如果我有一个具有200个属性的XElement呢?我希望C#/.net有一个更简单的解决方案。 - Numm3n
正确获取XML序列化属性并不容易(我发现这很容易出错)...我认为这并不需要更多的工作。此外,它有助于关注点分离 :-). - Richard

0
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类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接