-1

I have a XML file which has all information about a voyage and all details inside.

I want to read all records in XML file, after combining records I want to write it to SQL database.

So far I arranged getting header , company and voyage to array but getting details for all records to array I failed.

Here are my task to handle:

  • Select and read any XML Data to RAM by FileDialog (completed)
  • Create Arrays and Read XML data to Arrays (partly completed)
  • Write XML data to DataView (partly completed)
  • Create T-SQL INSERT Command (Partly completed)
  • Write Data to Database (Waiting to finish early steps)

While reading from XML to DataView I can get data to memory but could not seperated multi level data as requested.

The exact problem is trying to handle different levels of data in XML in every XML file I recieve.

foreach (var child in childElem.Elements("ManifestData"))
            {
                foreach(var x in child.Elements())
                {
                    var checkName = x.Name.ToString();

                    switch (checkName)
                    {
                        case "Company":
                            Globals.Companys.Clear();
                            foreach (var y in x.Elements())
                            {
                                Globals.Companys.Add(y.Name.ToString(), y.Value.ToString());
                            }
                            break;
                        case "Voyage":
                            Globals.Voyages.Clear();
                            foreach (var y in x.Elements())
                            {
                                Globals.Voyages.Add(y.Name.ToString(), y.Value.ToString());
                            }
                            break;
                        case "BLs":
                            int recs = 0;

                            Globals.BL.Clear();
                            textBox2.Clear();

                            foreach (var y in x.Elements())
                            {
                                
                                
                                   foreach (var z in x.Elements("units"))
                                   {
                                       Globals.Units.Add(y.Element("number").Value.ToString(), z.Value.ToString());

                                   }

                                Globals.BL.Add(y.Element("number").Value.ToString(), y.Value.ToString());

                                recs = recs + 1;
                                textBox2.AppendText("\n" + y.ToString());


                                string output = string.Join("\n", Globals.BL);
                                MessageBox.Show(output);
                                

                            }
                            break;
                        default:
                            break;
                    }
                }
            }

In my example XML you see that there is 3 BLs and all BL data has different levels.There can be hundreds of BLs with different levels of Goods & Dangerous Goods.

I am having trouble handling multi level XML data here.

I 'll be glad if you help me solve this very basic problem. I am hoping to learn and leave it for the people to figure out to understand making desktop XML reader application for their own DBs.

Here is the XML Data example You can find all sources here : Project Reading XMLbyC#

melic
  • 266
  • 2
  • 15
  • 4
    please provide a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example), not your entire code-base. No-one here will scan your entire code for errors, you have to provide your attempts and where **specifically** you´re stuck. – MakePeaceGreatAgain Mar 09 '21 at 13:22
  • " read any XML Data to RAM" show us the code for this please. After looking at your XML it seems that it could be represented by a class structure. The only code you would then need it [described here](https://stackoverflow.com/questions/364253/how-to-deserialize-xml-document) the rest is accessing variables from your representation class and distributing them. – Mong Zhu Mar 09 '21 at 13:28
  • I fixed my post , I should notice yout point. – melic Mar 09 '21 at 14:34

1 Answers1

2

The xml processing part can be made simple by deserializing your xml into c# classes which you can then use to do whatever you want.

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

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

[XmlRoot(ElementName = "Header")]
public class Header
{
    [XmlElement(ElementName = "sender")]
    public string Sender { get; set; }
    [XmlElement(ElementName = "reciever")] 
    public string Reciever { get; set; }

    [XmlElement(ElementName = "timeOfDocument")]
    public string TimeOfDocument { get; set; }

    [XmlElement(ElementName = "typeOfMessage")]
    public string TypeOfMessage { get; set; }
}


// Then when you want to get the xml deserialized into your class hierarchy


var xmlSerializer = new XmlSerializer(typeof(ManifestMessage));
var manifestMessage = xmlSerializer.Deserialize(data) as ManifestMessage;

// now you can use this object to drill down the whole hierarchy

Console.WriteLine(xmlData.Header.Sender);
Console.WriteLine(xmlData.ManifestData.Company.ComanyName);
Console.WriteLine(xmlData.ManifestData.Voyage.CrewNumber);
foreach (var bl in xmlData.ManifestData.BLs.BL)
{
    Console.WriteLine(bl.Collect);
    Console.WriteLine(bl.Consegnee.Name);
    Console.WriteLine(bl.Customer.Name);
}

You can use https://xmltocsharp.azurewebsites.net/ site to generate the whole c# class hierarchy from your xml.

Console.WriteLine is just for demo purpose you can adopt it according to your needs.

Ashraf Ali
  • 573
  • 4
  • 9
  • thank you for the link! very very usefull! have an upvote – Mong Zhu Mar 09 '21 at 14:07
  • Thanks for the link and the code , I will check and try to adapt my code to it but I was trying to figure out how to handle if xml is getting changed (Can be seen in BLs they different levels of records). In my example it was Goods and Dangerous Goods. – melic Mar 09 '21 at 14:16
  • 1
    You can add all the different combinations of `BLs` children to your xml file and let the generator generate classes for all , but you will have to tweak the xml through attribute to make something optional if they are not always present, like `[XmlRoot(ElementName = "AnotherBLChild", IsNullable = true)]` – Ashraf Ali Mar 09 '21 at 14:27
  • So it is the best way to create all possible combinations and when there is no data there just sending null to database is an option ; great sight of view . thanks for the idea. – melic Mar 09 '21 at 14:33
  • 1
    @melic If this answered your question can you please mark the answer. – Ashraf Ali Mar 09 '21 at 14:42
  • @AshrafAli I liked you approach however it is not my answer for my problem here yet; so I will try to adapt yours to my code if I can be succeded I'd love to mark it as an answer ; I 'll be glad about it. Btw did you check the code and click FillDataGrid to see the exact problem ? I can not handle deeper multi levels to my loop to handle it – melic Mar 09 '21 at 15:02
  • The aim in my code is at the end handling and extracting data from any level an uknown xml files and create Insert T-SQL sentences for inserting to Database.With your solution which seems like a good way to do it however it requires a standart schema of a specific XML file. For handling a XML your approach seems the best way which I wasn't knowing about. – melic Mar 10 '21 at 11:03