【问题标题】:C# Deserialization in LINQ-to-XMLLINQ-to-XML 中的 C# 反序列化
【发布时间】:2018-09-27 22:21:43
【问题描述】:

我有一个具有以下结构的 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <MIRs>
    <MIR id="1" number="1" revision="0">
      <issue_data>
        <issue_date>28-9-2018</issue_date>
        <from>Foo</from>
        <to>Foo</to>
        <author>Foo</author>
        <attn>Foo</attn>
        <field>Foo</field>
        <material_group>Foo</material_group>
        <related_sub>Foo</related_sub>
      </issue_data>
      <reply_data>
        <reply_date></reply_date>
        <action_code></action_code>
        <reply_from />
      </reply_data>
      <receive_data>
        <receive_date />
        <receive_by />
      </receive_data>
      <items>
        <item>
          <serial>1</serial>
          <boq_code>Foo-01</boq_code>
          <item_details>Foo</item_details>
          <model />
          <manufacturer>Foo</manufacturer>
          <size>1"</size>
          <uom>mt</uom>
          <qty>240</qty>
          <approval>Approved</approval>
          <approved_qty>240</approved_qty>
          <is_lumbsum>false</is_lumbsum>
        </item>
      </items>
      <submission_data>
        <submitted>false</submitted>
        <status>1</status>
      </submission_data>
    </MIR>

  </MIRs>
</root>

在我的项目中,我有这个代码:

var x =
            (from mir in XmlFiles.MIR.Root.Descendants("MIR")
             select new
             {
                 Number = mir.Attribute("number").Value,
                 Revision = mir.Attribute("revision").Value,
                 From = mir.Element("issue_data").Element("from").Value,
                 Material = mir.Element("issue_data").Element("material_group").Value,
                 Field = mir.Element("issue_data").Element("field").Value,
                 Submittal = mir.Element("issue_data").Element("related_sub").Value,
                 To = mir.Element("issue_data").Element("to").Value,
                 Atten = mir.Element("issue_data").Element("attn").Value,
                 IssueDate = Convert.ToDateTime(mir.Element("issue_data").Element("issue_date").Value),
                 ReplyDate = mir.Element("reply_data").Element("reply_date").Value,
                 ActionCode = mir.Element("reply_data").Element("action_code").Value,
                 Author = mir.Element("issue_data").Element("author").Value,
                 IsSubmitted = Convert.ToBoolean(mir.Element("submission_data").Element("submitted").Value),
                 Status = mir.Element("submission_data").Element("status").Value
             }).First();

我想做的是像这样以 LINQ-to-Entities 样式编写代码

Number = mir.Attribute("number").Value

像:

数字 = mir.Number

修订 = mir.Revision

发件人 = mir.IssueData.From

材料 = mir.IssueData.MaterialGroup

等等其余的代码,我搜索并阅读了关于反序列化以及如何做到这一点并添加了我的对象(类)但我不知道如何在我的代码中使用它们,假设在 Linq-to 中是可能的-XML

反序列化的代码是:

using System;
using System.Xml.Serialization;
using System.Collections.Generic;

namespace SDM
{
    [XmlRoot(ElementName = "issue_data")]
    public class IssueData
    {
        [XmlElement(ElementName = "issue_date")]
        public string IssueDate { get; set; }

        [XmlElement(ElementName = "from")]
        public string From { get; set; }

        [XmlElement(ElementName = "to")]
        public string To { get; set; }

        [XmlElement(ElementName = "author")]
        public string Author { get; set; }

        [XmlElement(ElementName = "attn")]
        public string Attn { get; set; }

        [XmlElement(ElementName = "field")]
        public string Field { get; set; }

        [XmlElement(ElementName = "material_group")]
        public string MaterialGroup { get; set; }

        [XmlElement(ElementName = "related_sub")]
        public string RelatedSub { get; set; }
    }

    [XmlRoot(ElementName = "reply_data")]
    public class ReplyData
    {
        [XmlElement(ElementName = "reply_date")]
        public string ReplyDate { get; set; }

        [XmlElement(ElementName = "action_code")]
        public string ActionCode { get; set; }

        [XmlElement(ElementName = "reply_from")]
        public string ReplyFrom { get; set; }
    }

    [XmlRoot(ElementName = "receive_data")]
    public class ReceiveData
    {
        [XmlElement(ElementName = "receive_date")]
        public string ReceiveDate { get; set; }

        [XmlElement(ElementName = "receive_by")]
        public string ReceiveBy { get; set; }
    }

    [XmlRoot(ElementName = "item")]
    public class Item
    {
        [XmlElement(ElementName = "serial")]
        public string Serial { get; set; }

        [XmlElement(ElementName = "boq_code")]
        public string BoqCode { get; set; }

        [XmlElement(ElementName = "item_details")]
        public string ItemDetails { get; set; }

        [XmlElement(ElementName = "model")]
        public string Model { get; set; }

        [XmlElement(ElementName = "manufacturer")]
        public string Manufacturer { get; set; }

        [XmlElement(ElementName = "size")]
        public string Size { get; set; }

        [XmlElement(ElementName = "uom")]
        public string UoM { get; set; }

        [XmlElement(ElementName = "qty")]
        public string Quantity { get; set; }

        [XmlElement(ElementName = "approval")]
        public string Approval { get; set; }

        [XmlElement(ElementName = "approved_qty")]
        public string ApprovedQuantity { get; set; }

        [XmlElement(ElementName = "is_lumbsum")]
        public string IsLumbsum { get; set; }
    }

    [XmlRoot(ElementName = "items")]
    public class Items
    {
        [XmlElement(ElementName = "item")]
        public Item Item { get; set; }
    }

    [XmlRoot(ElementName = "submission_data")]
    public class SubmissionData
    {
        [XmlElement(ElementName = "submitted")]
        public string Submitted { get; set; }

        [XmlElement(ElementName = "status")]
        public string Status { get; set; }
    }

    [XmlRoot(ElementName = "MIR")]
    public class MIR
    {
        [XmlElement(ElementName = "issue_data")]
        public IssueData IssueData { get; set; }

        [XmlElement(ElementName = "reply_data")]
        public ReplyData ReplyData { get; set; }

        [XmlElement(ElementName = "receive_data")]
        public ReceiveData ReceiveData { get; set; }

        [XmlElement(ElementName = "items")]
        public Items Items { get; set; }

        [XmlElement(ElementName = "submission_data")]
        public SubmissionData SubmissionData { get; set; }

        [XmlAttribute(AttributeName = "id")]
        public string ID { get; set; }

        [XmlAttribute(AttributeName = "number")]
        public string Number { get; set; }

        [XmlAttribute(AttributeName = "revision")]
        public string Revision { get; set; }
    }

    [XmlRoot(ElementName = "MIRs")]
    public class MIRs
    {
        [XmlElement(ElementName = "MIR")]
        public MIR MIR { get; set; }
    }

    [XmlRoot(ElementName = "root")]
    public class Root
    {
        [XmlElement(ElementName = "MIRs")]
        public MIRs MIRs { get; set; }
    }

}

【问题讨论】:

    标签: c# xml linq deserialization


    【解决方案1】:

    由于 MIRs 是 MIR 的集合,那么你应该修改 Root 类为 -

    [XmlRoot(ElementName = "root")]
    public class Root
    {
        [XmlArray(ElementName = "MIRs")]
        public List<MIR> MIRs { get; set; }
    }
    

    你不需要 MIRs 类,所以删除那个。

    现在您可以使用 XmlSerializer 将 xmldata 反序列化为实体,如下所示。

    XmlSerializer serializer = new XmlSerializer(typeof(Root));
    Root root;
    using (TextReader reader = new StringReader(xmlData))
    {
        root = (Root)serializer.Deserialize(reader);
    }
    

    现在您可以在实体上编写 LINQ 查询,如下所示 -

    // Linq queries
    root.MIRs.Select(mir => new {
        Number = mir.Number,
        Revesion = mir.Revision
    }).FirstOrDefault();
    

    如果你是从文件中读取 XML 数据,那么你应该使用 FileStrem 而不是 TextReader。

    using (FileStream fileStream = new FileStream("FilePath", FileMode.Open))
    {
        root = (Root)serializer.Deserialize(fileStream);
    }
    

    【讨论】:

    • 您的解决方案将不起作用。如果删除 MIRs 类,则必须将 From :[XmlElement(ElementName = "MIR")] 更改为:[XmlArray(ElementName = "MIR")]
    • @jdweng - 同意,感谢您的指出。更新了答案。
    • 是的,就是这样,非常感谢@Vinit。这就是我现在正在寻找的东西,我可以轻松地轻松修改我的 XML 结构,而无需遍历项目代码。另外,感谢 [jdweng]
    猜你喜欢
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    相关资源
    最近更新 更多