Reputation: 593
I have an XML file with the following structure:
<?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>
In my project I have this code:
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();
What I trying to do is to write the code in a LINQ-to-Entities style like this
Number = mir.Attribute("number").Value
to be like:
Number = mir.Number
Revision = mir.Revision
From = mir.IssueData.From
Material = mir.IssueData.MaterialGroup
and so on the rest of the code, I searched and read about deserialization and how to do it andadded my objects (classes) but I don't know how to use them in my code assuming it is possible in Linq-to-XML
The code for the deserialization is:
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; }
}
}
Upvotes: 1
Views: 116
Reputation: 2607
As MIRs is collection of MIR, then you should modify the Root clsss as -
[XmlRoot(ElementName = "root")]
public class Root
{
[XmlArray(ElementName = "MIRs")]
public List<MIR> MIRs { get; set; }
}
You don't need the MIRs class, so delete that one.
Now you can Deserialize the xmldata to entity using XmlSerializer like below.
XmlSerializer serializer = new XmlSerializer(typeof(Root));
Root root;
using (TextReader reader = new StringReader(xmlData))
{
root = (Root)serializer.Deserialize(reader);
}
Now you can write LINQ queries on the entity like below -
// Linq queries
root.MIRs.Select(mir => new {
Number = mir.Number,
Revesion = mir.Revision
}).FirstOrDefault();
if you are reading the XML data from file, then you should FileStrem instead of TextReader.
using (FileStream fileStream = new FileStream("FilePath", FileMode.Open))
{
root = (Root)serializer.Deserialize(fileStream);
}
Upvotes: 1