C # десериализация в LINQ-to-XML - PullRequest
       23

C # десериализация в LINQ-to-XML

0 голосов
/ 28 сентября 2018

У меня есть 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"). Значение

должно быть таким:

Number = mir.Number

Revision = mir.Revision

From = mir.IssueData.From

Material = 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; }
    }

}

1 Ответ

0 голосов
/ 28 сентября 2018

Поскольку MIR - это коллекция MIR, вам следует изменить Root clsss как -

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

Вам не нужен класс MIR, поэтому удалите его.

Теперь выможно десериализовать xmldata в сущность, используя XmlSerializer, как показано ниже.

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);
}
...