locked
Parse Multilevel XML file into List or Array RRS feed

  • Question

  • <Config_settings>
    	<exclude_folders>
    		<ExFolder1>C:\BACKUP</ExFolder1>
    		<ExFolder2>C:\sss</ExFolder2>
    		<ExFolder3>C:\ccc</ExFolder3>
    	</exclude_folders>
    	<scan_folders>
    		<scanfolder1>C:\Program Files (x86)\xxx\yyy\</scanfolder1>
    		<scanfolder2>C:\inetpub\wwwroot\xxx\</scanfolder2>
    		<scanfolder3>C:\inetpub\wwwroot\WebServices\Current\</scanfolder3>
    		<scanfolder4>C:\Program Files\sss\bin\xxx\</scanfolder4>
    		<scanfolder5>C:\Program Files\ccc\Reports\Generic\</scanfolder5>
    		<scanfolder6>C:\xxx\App_Server\yyy\ETL\</scanfolder6>
    		<scanfolder7>C:\Apps\yyy\</scanfolder7>
    	</scan_folders>
    	<exclude_filenames>
    		<file1>yyy.exe.config</file1>
    		<file2>yyy.yyy.yyy.yyy.ETL.ConfigUtil.exe.config</file2>
    		<file3>xxx.yyy.zzz.exe.config</file3>
    	</exclude_filenames>
    	<exclude_dates>
    		<date1>09/30/2014</date1>
    		<date2>09/25/2014</date2>
    		<date3>09/02/2014</date3>
    	</exclude_dates>
    	<exclude_fileextensions>
    		<exfileext1>.xml</exfileext1>
    		<exfileext2>.exe.config</exfileext2>
    		<exfileext3>.psr</exfileext3>
    		<exfileext4>.xls</exfileext4>
    		<exfileext5>.pdf</exfileext5>
    	</exclude_fileextensions>
    	<include_fileextensions>
    		<incfileext1>.dll</incfileext1>
    		<incfileext2>.xls</incfileext2>
    		<incfileext3>.exe</incfileext3>
    	</include_fileextensions>
    	<scheduled_tasks>
    		<task1>xxx yyy</task1>
    		<task2>xxx zzz</task2>
    		<task3>aaa bbb</task3>
    		<task4>xxx yyy</task4>
    	</scheduled_tasks>
    	<app_pools>
    		<app1>yyy</app1>
    		<app2>yyy</app2>
    	</app_pools>
    	<serviceslist>
    		<service1>yyy</service1>
    		<service2>yyy yyy yyy</service2>
    	</serviceslist>
    </Config_settings>

    The above is my XML file which I am trying to  read into individual collections. exclude_folders into one array, exclude_filenames into another araay or list and so on. Each of this sub nodes can have n number of childs in it. I tried to do the best using LINQ to XML and somehow struggling to achieve it..

    I Keep trying while I POST this here..

    My current code below

                      var lv1s = from lv1 in XMLfilterbyfilenameLOAD.Descendants("exclude_filenames")
                                 select new
                                 {
                                     Header = lv1.Attribute("file1").Value
                                 };
    
                      //Loop through results
                      foreach (var lv1 in lv1s)
                      {
                          MessageBox.Show(lv1.Header);
    
    
                      }


    - Neuronring

    Thursday, October 2, 2014 1:51 PM

Answers

  • You can try an another way as follows:

    public void M()
            {
                string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Config_settings><exclude_folders><ExFolder1>C:\\BACKUP</ExFolder1><ExFolder2>C:\\sss</ExFolder2><ExFolder3>C:\\ccc</ExFolder3></exclude_folders><scan_folders><scanfolder1>C:\\Program Files (x86)\\xxx\\yyy\\</scanfolder1><scanfolder2>C:\\inetpub\\wwwroot\\xxx\\</scanfolder2><scanfolder3>C:\\inetpub\\wwwroot\\WebServices\\Current\\</scanfolder3><scanfolder4>C:\\Program Files\\sss\\bin\\xxx\\</scanfolder4><scanfolder5>C:\\Program Files\\ccc\\Reports\\Generic\\</scanfolder5><scanfolder6>C:\\xxx\\App_Server\\yyy\\ETL\\</scanfolder6><scanfolder7>C:\\Apps\\yyy\\</scanfolder7></scan_folders><exclude_filenames><file1>yyy.exe.config</file1><file2>yyy.yyy.yyy.yyy.ETL.ConfigUtil.exe.config</file2><file3>xxx.yyy.zzz.exe.config</file3></exclude_filenames><exclude_dates><date1>09/30/2014</date1><date2>09/25/2014</date2><date3>09/02/2014</date3></exclude_dates><exclude_fileextensions><exfileext1>.xml</exfileext1><exfileext2>.exe.config</exfileext2><exfileext3>.psr</exfileext3><exfileext4>.xls</exfileext4><exfileext5>.pdf</exfileext5></exclude_fileextensions><include_fileextensions><incfileext1>.dll</incfileext1><incfileext2>.xls</incfileext2><incfileext3>.exe</incfileext3></include_fileextensions><scheduled_tasks><task1>xxx yyy</task1><task2>xxx zzz</task2><task3>aaa bbb</task3><task4>xxx yyy</task4></scheduled_tasks><app_pools><app1>yyy</app1><app2>yyy</app2></app_pools><serviceslist><service1>yyy</service1><service2>yyy yyy yyy</service2></serviceslist></Config_settings>";
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                
                Dictionary<string, List<XmlNode>> d = new Dictionary<string,List<XmlNode>>();
                XmlNode x = xmlDoc.DocumentElement;
                foreach (XmlNode a in x)
                {
                    if (a.HasChildNodes)
                    {
                        List<XmlNode> list = new List<XmlNode>();
                        for (int i = 0; i < a.ChildNodes.Count; i++)
                        {
                            list.Add(a.ChildNodes[i]);
                        }
                        d.Add(a.Name,list);
                    }          
                 }
            }
      

    Now you have 9 lists respectively to 9 XmlNodes of Level1. The name of the list is the XmlNode.Name and members of the list are level1 XmlNode's childnodes. 

    • Marked as answer by Caillen Tuesday, October 14, 2014 3:20 AM
    Friday, October 3, 2014 2:58 PM
  • Thanks Hristo,

    I added it to the dictionary, but When I try to browse the dictionary whose values are a LIST, I am getting "System.Collections.Generic.List1[System.Xml.Linq.Xelement]. How do I over come this?

    And I want to load each parent into a separate List or Array. Like All The child nodes of <exclude_folders> into one list, all the child nodes of  <scan_folders> into another separate list and so on... 


    I made it like this., it is working

    /* Create  a dictionary */
                Dictionary<string, List<XElement>> d = new Dictionary<string, List<XElement>>();
    
               /* Create an array*/
    
                 Array a = parsedSettings.Root.Descendants().ToArray();
                
                 foreach(XElement item in a){
    
                        if (item.HasElements)
                        {
                            d.Add(item.Name.ToString(), item.Descendants().ToList());
                      
                        }
                    }
    
    
                 /* Declare the list one for each parent node */
    
    
              
                 List<string> exclude_folders_list = new List<string>();
                 List<string> scan_folders_list = new List<string>();
                 List<string> exclude_filenames_list = new List<string>();
                 List<string> exclude_dates_list = new List<string>();
                 List<string> exclude_fileextensions_list = new List<string>();
                 List<string> include_fileextensions_list = new List<string>();
                 List<string> scheduled_tasks_list = new List<string>();
                 List<string> app_pools_list = new List<string>();
                 List<string> services_list_list = new List<string>(); 
    
                 /* Access the dictionary in a lopp */
    
                 foreach (var parents in d)
                 {
                     string parentsValue = parents.Key;
                     var valuesString = d[parentsValue].ToList();
    
                     foreach (string childValues in valuesString)
                    {
                        if (parentsValue == "exclude_folders")
                        {
                            exclude_folders_list.Add(childValues);
                        }
                        else if (parentsValue == "scan_folders")
                         {
                             scan_folders_list.Add(childValues);
                         }
                        else if (parentsValue == "exclude_filenames")
                        {
                            exclude_filenames_list.Add(childValues);
                        }
                        else if (parentsValue == "exclude_dates")
                        {
                            exclude_dates_list.Add(childValues);
                        }
                        else if (parentsValue == "exclude_fileextensions")
                        {
                            exclude_fileextensions_list.Add(childValues);
                        }
                        else if (parentsValue == "include_fileextensions")
                        {
                            include_fileextensions_list.Add(childValues);
                        }
                        else if (parentsValue == "scheduled_tasks")
                        {
                            scheduled_tasks_list.Add(childValues);
                        }
                        else if (parentsValue == "app_pools")
                        {
                            app_pools_list.Add(childValues);
                        }
                        else if (parentsValue == "services_list")
                        {
                            services_list_list.Add(childValues);
                        }
                    }
    
                 }



    • Edited by neuronring Thursday, October 2, 2014 4:42 PM
    • Marked as answer by Caillen Tuesday, October 14, 2014 3:22 AM
    Thursday, October 2, 2014 3:49 PM

All replies

  • Hello neuronring,

    I would recommend to use a dictionary to save the settings values. The following code could should work for your scenario:

    string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Config_settings><exclude_folders><ExFolder1>C:\\BACKUP</ExFolder1><ExFolder2>C:\\sss</ExFolder2><ExFolder3>C:\\ccc</ExFolder3></exclude_folders><scan_folders><scanfolder1>C:\\Program Files (x86)\\xxx\\yyy\\</scanfolder1><scanfolder2>C:\\inetpub\\wwwroot\\xxx\\</scanfolder2><scanfolder3>C:\\inetpub\\wwwroot\\WebServices\\Current\\</scanfolder3><scanfolder4>C:\\Program Files\\sss\\bin\\xxx\\</scanfolder4><scanfolder5>C:\\Program Files\\ccc\\Reports\\Generic\\</scanfolder5><scanfolder6>C:\\xxx\\App_Server\\yyy\\ETL\\</scanfolder6><scanfolder7>C:\\Apps\\yyy\\</scanfolder7></scan_folders><exclude_filenames><file1>yyy.exe.config</file1><file2>yyy.yyy.yyy.yyy.ETL.ConfigUtil.exe.config</file2><file3>xxx.yyy.zzz.exe.config</file3></exclude_filenames><exclude_dates><date1>09/30/2014</date1><date2>09/25/2014</date2><date3>09/02/2014</date3></exclude_dates><exclude_fileextensions><exfileext1>.xml</exfileext1><exfileext2>.exe.config</exfileext2><exfileext3>.psr</exfileext3><exfileext4>.xls</exfileext4><exfileext5>.pdf</exfileext5></exclude_fileextensions><include_fileextensions><incfileext1>.dll</incfileext1><incfileext2>.xls</incfileext2><incfileext3>.exe</incfileext3></include_fileextensions><scheduled_tasks><task1>xxx yyy</task1><task2>xxx zzz</task2><task3>aaa bbb</task3><task4>xxx yyy</task4></scheduled_tasks><app_pools><app1>yyy</app1><app2>yyy</app2></app_pools><serviceslist><service1>yyy</service1><service2>yyy yyy yyy</service2></serviceslist></Config_settings>";
    XDocument x = XDocument.Parse(xml);
    Dictionary<string, List<XElement>> d = new Dictionary<string, List<XElement>>();
    Array a = x.Root.Descendants().ToArray();
    foreach(XElement item in a){
         if (item.HasElements){
               d.Add(item.Name.ToString(), item.Descendants().ToList());
         }
    }

    Regards,
    Hristo Valev
    Developer-Hotline for MSDN Online Germany

    Disclaimer:
    Please take into consideration, that further inquiries cannot or will be answered with delay.
    For further information please contact us per telephone through the MSDN-Entwickler-Hotline: http://www.msdn-online.de/Hotline
    MSDN-Entwickler-Hotline: Fast and professional help for software developers free of charge!

    For this post by the MSDN-Entwickler-Hotline the following terms and conditions apply: Trademarks, Privacy as well as the separate terms of use for the MSDN-Entwickler-Hotline.

    Thursday, October 2, 2014 3:22 PM
  • Thanks Hristo,

    I added it to the dictionary, but When I try to browse the dictionary whose values are a LIST, I am getting "System.Collections.Generic.List1[System.Xml.Linq.Xelement]. How do I over come this?

    And I want to load each parent into a separate List or Array. Like All The child nodes of <exclude_folders> into one list, all the child nodes of  <scan_folders> into another separate list and so on... 


    I made it like this., it is working

    /* Create  a dictionary */
                Dictionary<string, List<XElement>> d = new Dictionary<string, List<XElement>>();
    
               /* Create an array*/
    
                 Array a = parsedSettings.Root.Descendants().ToArray();
                
                 foreach(XElement item in a){
    
                        if (item.HasElements)
                        {
                            d.Add(item.Name.ToString(), item.Descendants().ToList());
                      
                        }
                    }
    
    
                 /* Declare the list one for each parent node */
    
    
              
                 List<string> exclude_folders_list = new List<string>();
                 List<string> scan_folders_list = new List<string>();
                 List<string> exclude_filenames_list = new List<string>();
                 List<string> exclude_dates_list = new List<string>();
                 List<string> exclude_fileextensions_list = new List<string>();
                 List<string> include_fileextensions_list = new List<string>();
                 List<string> scheduled_tasks_list = new List<string>();
                 List<string> app_pools_list = new List<string>();
                 List<string> services_list_list = new List<string>(); 
    
                 /* Access the dictionary in a lopp */
    
                 foreach (var parents in d)
                 {
                     string parentsValue = parents.Key;
                     var valuesString = d[parentsValue].ToList();
    
                     foreach (string childValues in valuesString)
                    {
                        if (parentsValue == "exclude_folders")
                        {
                            exclude_folders_list.Add(childValues);
                        }
                        else if (parentsValue == "scan_folders")
                         {
                             scan_folders_list.Add(childValues);
                         }
                        else if (parentsValue == "exclude_filenames")
                        {
                            exclude_filenames_list.Add(childValues);
                        }
                        else if (parentsValue == "exclude_dates")
                        {
                            exclude_dates_list.Add(childValues);
                        }
                        else if (parentsValue == "exclude_fileextensions")
                        {
                            exclude_fileextensions_list.Add(childValues);
                        }
                        else if (parentsValue == "include_fileextensions")
                        {
                            include_fileextensions_list.Add(childValues);
                        }
                        else if (parentsValue == "scheduled_tasks")
                        {
                            scheduled_tasks_list.Add(childValues);
                        }
                        else if (parentsValue == "app_pools")
                        {
                            app_pools_list.Add(childValues);
                        }
                        else if (parentsValue == "services_list")
                        {
                            services_list_list.Add(childValues);
                        }
                    }
    
                 }



    • Edited by neuronring Thursday, October 2, 2014 4:42 PM
    • Marked as answer by Caillen Tuesday, October 14, 2014 3:22 AM
    Thursday, October 2, 2014 3:49 PM
  • I made it like this., it is working

    /* Create a dictionary */

    ...

    Seems that you've already found the solution. You could also use xsd.exe to generate a class file for the XML, then you could deserialize the XML to an object. But if you want to change the xml file at runtime, XmlDocument or Linq to XML will be better.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, October 3, 2014 8:27 AM
  • Thanks Caillen,

    I am very happy to see you saying that I found the solution.I am pretty new to Programming world and I did not know anything about .NET framework or C# or Programming when I started my new career two months ago.

    I learned everything here at Social.MSDN. There are lot of other forums, where the experts trying to be little difficult on the people who ask questionsin complete ignorance. I could understand that they help me (and the users like me)  to get some education and motivate me to try learning things on my own.. But most of the times, it demotivates the beginners and put them down mentally. Because novice users like me really need someone to guide and help with some love..

    There are few Gurus [teachers] at social.msdn that I would like to thank sincerely. They are the "sculptors" who shaped me to a meaningful sculpture. 

    "Andy O Neil and Michael Taylor." - I am thankful to you all the time..


    - Neuronring

    Friday, October 3, 2014 2:38 PM
  • You can try an another way as follows:

    public void M()
            {
                string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Config_settings><exclude_folders><ExFolder1>C:\\BACKUP</ExFolder1><ExFolder2>C:\\sss</ExFolder2><ExFolder3>C:\\ccc</ExFolder3></exclude_folders><scan_folders><scanfolder1>C:\\Program Files (x86)\\xxx\\yyy\\</scanfolder1><scanfolder2>C:\\inetpub\\wwwroot\\xxx\\</scanfolder2><scanfolder3>C:\\inetpub\\wwwroot\\WebServices\\Current\\</scanfolder3><scanfolder4>C:\\Program Files\\sss\\bin\\xxx\\</scanfolder4><scanfolder5>C:\\Program Files\\ccc\\Reports\\Generic\\</scanfolder5><scanfolder6>C:\\xxx\\App_Server\\yyy\\ETL\\</scanfolder6><scanfolder7>C:\\Apps\\yyy\\</scanfolder7></scan_folders><exclude_filenames><file1>yyy.exe.config</file1><file2>yyy.yyy.yyy.yyy.ETL.ConfigUtil.exe.config</file2><file3>xxx.yyy.zzz.exe.config</file3></exclude_filenames><exclude_dates><date1>09/30/2014</date1><date2>09/25/2014</date2><date3>09/02/2014</date3></exclude_dates><exclude_fileextensions><exfileext1>.xml</exfileext1><exfileext2>.exe.config</exfileext2><exfileext3>.psr</exfileext3><exfileext4>.xls</exfileext4><exfileext5>.pdf</exfileext5></exclude_fileextensions><include_fileextensions><incfileext1>.dll</incfileext1><incfileext2>.xls</incfileext2><incfileext3>.exe</incfileext3></include_fileextensions><scheduled_tasks><task1>xxx yyy</task1><task2>xxx zzz</task2><task3>aaa bbb</task3><task4>xxx yyy</task4></scheduled_tasks><app_pools><app1>yyy</app1><app2>yyy</app2></app_pools><serviceslist><service1>yyy</service1><service2>yyy yyy yyy</service2></serviceslist></Config_settings>";
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                
                Dictionary<string, List<XmlNode>> d = new Dictionary<string,List<XmlNode>>();
                XmlNode x = xmlDoc.DocumentElement;
                foreach (XmlNode a in x)
                {
                    if (a.HasChildNodes)
                    {
                        List<XmlNode> list = new List<XmlNode>();
                        for (int i = 0; i < a.ChildNodes.Count; i++)
                        {
                            list.Add(a.ChildNodes[i]);
                        }
                        d.Add(a.Name,list);
                    }          
                 }
            }
      

    Now you have 9 lists respectively to 9 XmlNodes of Level1. The name of the list is the XmlNode.Name and members of the list are level1 XmlNode's childnodes. 

    • Marked as answer by Caillen Tuesday, October 14, 2014 3:20 AM
    Friday, October 3, 2014 2:58 PM