繁体   English   中英

如何将 xml 元素值反序列化为 C# 类属性

[英]How to deserialise xml element values into C# class properties

这是我第一次在 StackOverflow 上发帖,所以请原谅任何错误。 鉴于此 xml:

<document name="doc1.pdf">
  <propertyValues>      
    <propertyValue><name>InvoiceID</name><value>123</value></propertyValue>
    <propertyValue><name>CompanyName</name><value>Company1</value></propertyValue>
    <propertyValue><name>VendorName</name><value>Vendor1</value></propertyValue>    
    <propertyValue><name>GrossAmt</name><value>176.33</value></propertyValue>
    <propertyValue><name>InvoiceDate</name><value>26-03-2019</value></propertyValue>
  </propertyValues>
</document>
<document name="doc2.pdf">
  <propertyValues>      
    <propertyValue><name>InvoiceID</name><value>223</value></propertyValue>
    <propertyValue><name>CompanyName</name><value>Company2</value></propertyValue>
    <propertyValue><name>VendorName</name><value>Vendor2</value></propertyValue>    
    <propertyValue><name>GrossAmt</name><value>5300.88</value></propertyValue>
    <propertyValue><name>InvoiceDate</name><value>31-03-2019</value></propertyValue>
  </propertyValues>
</document>

有没有更简单的方法将它反序列化为 C# 类,例如。

    public class Invoice
    {
        public string InvoiceId { get; set; }
        public string CompanyName { get; set; }
        public string VendorName { get; set; }
        public decimal GrossAmt { get; set; }
        public DateTime InvoiceDate { get; set; }
    }

当 xml 元素名称映射到属性名称时,反序列化很简单,但在这种情况下它是一个值。 试图避免遍历 xml 并手动提取值。

至少使用标准的 .Net XMLSerializer 没有办法用属性来装饰你的类来让序列化按照你的意愿工作。 但是你可以使用这样的类结构来解决这个问题:

public class InvoiceList {
    [XmlElement("document")]
    public Invoice[] Invoices { get; set; }
}

public class Invoice {
    [XmlIgnore]
    public string InvoiceId => this.PropertyValues.First(p => p.Name == "InvoiceID").Value;
    [XmlIgnore]
    public string CompanyName => this.PropertyValues.First(p => p.Name == "CompanyName").Value;
    [XmlIgnore]
    public string VendorName => this.PropertyValues.First(p => p.Name == "VendorName").Value;
    [XmlIgnore]
    public decimal GrossAmt => decimal.Parse(this.PropertyValues.First(p => p.Name == "GrossAmt").Value);
    [XmlIgnore]
    public DateTime InvoiceDate => DateTime.Parse(this.PropertyValues.First(p => p.Name == "InvoiceDate").Value);
    [XmlArray("propertyValues")]
    [XmlArrayItem("propertyValue")]
    public PropertyValue[] PropertyValues { get; set; }
}

public class PropertyValue {
    [XmlElement("name")]
    public string Name { get; set; }
    [XmlElement("value")]
    public string Value { get; set; }
}

Invoice 类看起来仍然相同(至少对于阅读而言,写作需要更多的工作,但我希望你能明白)。 当然,需要一些更有意义的错误处理。

xml 字符串需要包含在<InvoiceList>...</InvoiceList>标记中才能工作:

<?xml version="1.0" encoding="UTF-8"?>
<InvoiceList>
  <document name="doc1.pdf">
    <propertyValues>
      <propertyValue><name>InvoiceID</name><value>123</value></propertyValue>
      <propertyValue><name>CompanyName</name><value>Company1</value></propertyValue>
      <propertyValue><name>VendorName</name><value>Vendor1</value></propertyValue>
      <propertyValue><name>GrossAmt</name><value>176.33</value></propertyValue>
      <propertyValue><name>InvoiceDate</name><value>26-03-2019</value></propertyValue>
    </propertyValues>
  </document>
  <document name="doc2.pdf">
    <propertyValues>
      <propertyValue><name>InvoiceID</name><value>223</value></propertyValue>
      <propertyValue><name>CompanyName</name><value>Company2</value></propertyValue>
      <propertyValue><name>VendorName</name><value>Vendor2</value></propertyValue>
      <propertyValue><name>GrossAmt</name><value>5300.88</value></propertyValue>
      <propertyValue><name>InvoiceDate</name><value>31-03-2019</value></propertyValue>
    </propertyValues>
  </document>
</InvoiceList>

反序列化本身:

var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><InvoiceList><document name=\"doc1.pdf\"><propertyValues><propertyValue><name>InvoiceID</name><value>123</value></propertyValue><propertyValue><name>CompanyName</name><value>Company1</value></propertyValue><propertyValue><name>VendorName</name><value>Vendor1</value></propertyValue><propertyValue><name>GrossAmt</name><value>176.33</value></propertyValue><propertyValue><name>InvoiceDate</name><value>26-03-2019</value></propertyValue></propertyValues></document><document name=\"doc2.pdf\"><propertyValues><propertyValue><name>InvoiceID</name><value>223</value></propertyValue><propertyValue><name>CompanyName</name><value>Company2</value></propertyValue><propertyValue><name>VendorName</name><value>Vendor2</value></propertyValue><propertyValue><name>GrossAmt</name><value>5300.88</value></propertyValue><propertyValue><name>InvoiceDate</name><value>31-03-2019</value></propertyValue></propertyValues></document></InvoiceList>";
using var stream = new MemoryStream();
using var writer = new StreamWriter(stream);
writer.Write(xml);
writer.Flush();
stream.Position = 0;

using var serializer = new XmlSerializer(typeof(InvoiceList));
var list = (InvoiceList)serializer.Deserialize(stream);

foreach (var i in list.Invoices) {
    Console.WriteLine($"{i.InvoiceId}, {i.CompanyName}");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM