question

SAbijith-9493 avatar image
0 Votes"
SAbijith-9493 asked SAbijith-9493 commented

Deserializing XML file

Hi All,
I am facing issues while deserializing an XML in C#. I am currently using .Net framework 4.6.1.
I am having an XML file which contains a few details which i need to use in my C# WPF application. I am currently facing some issues with regard to this:

I currently have one XML file which i am able to deserialize by mapping all the fields in the XML file to specific classes in the application.

But the problem is that this XML file is not static, it is dynamic. As a result i am not able to map any additional fields in the XML file using the classes that i already have in the application. Hence the deserialization fails in case any additional fields are present in the XML file.

I dont need all the fields in the XML file, i only need about 5 values from the XML file.

Is there any way that this can be made generic so that it will be able to handle the dynamic XML file with the existing classes?

Any help will be appreciated.
Thank you!!

dotnet-csharp
· 9
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


Which code are you using to deserialize XML into C# objects? Which errors do you get?

If possible, also show a sample XML that causes the error.

0 Votes 0 ·

Hi Viorel-1,

I use the below code for deserializing the XML file:

sample_export zabbixHostsDetails = (sample_export)serializer.Deserialize(reader);

where,
sample_export is a class which contains variables to handle the XML fields.
reader is an object of Streamreader class.

I get an invalid operation exception when i try to deserialize.

I have attached a sample of the XML file with no issue and the one that is causing the issue.
As you can see in the XML file which has issues, there is an extra field named 'items' which seems to be causing the issue. If that part is removed, the issue is resolved.

123508-xml-file-with-no-issue.txt123532-xml-file-with-issue.txt


0 Votes 0 ·

What class are you using for serializer?


0 Votes 0 ·
Show more comments

1 Answer

JackJJun-MSFT avatar image
0 Votes"
JackJJun-MSFT answered SAbijith-9493 commented

@SAbijith-9493 , you could design a dynamic class to adapt your dynamic xml file.

First, you could create the following class to inherit from the class DynamicObject.

 using System.Dynamic;
 using System.Linq;
 using System.Xml.Linq;
    
  class Program
 {
     static void Main(string[] args)
     {
    
         string xml2 = File.ReadAllText("Issue.txt");
         dynamic zabbix_export = DynamicXml.Parse(xml2);
         var namelist = zabbix_export.hosts.host;
         foreach (var item in namelist)
         {
             Console.WriteLine(item.name);          //Get Device Name
         }
         foreach (var host in namelist)
         {
             foreach (var inter in host.interfaces.@interface)
             {
                 Console.WriteLine(inter.ip);    //Get ip
             }
         }
    
         foreach (var host in namelist)                      
         {
             var tags = host.tags.tag;
             if (tags.ToString().Contains("DynamicXml"))
             {
                 if(tags.tag.ToString()== "Model_Name")
                 {
                     Console.WriteLine(tags.tag + "**" + tags.value);      //Get tag called Model_Name and its value
                 }
                      
                             
             }
             else
             {
                 var newtag = host.tags.tag;
                 foreach (var item in newtag)
                 {
                     if(item.tag.ToString() == "Model_Name")
                     {
                         Console.WriteLine(item.tag+"**"+item.value);
                     }
                 }
                    
             }
    
    
               
         }
          
         Console.ReadKey();
    
     }
 }
 public class DynamicXml : DynamicObject
 {
     XElement _root;
     private DynamicXml(XElement root)
     {
         _root = root;
     }
    
     public static DynamicXml Parse(string xmlString)
     {
         return new DynamicXml(XDocument.Parse(xmlString).Root);
     }
    
     public static DynamicXml Load(string filename)
     {
         return new DynamicXml(XDocument.Load(filename).Root);
     }
    
     public override bool TryGetMember(GetMemberBinder binder, out object result)
     {
         result = null;
    
         var att = _root.Attribute(binder.Name);
         if (att != null)
         {
             result = att.Value;
             return true;
         }
    
         var nodes = _root.Elements(binder.Name);
         if (nodes.Count() >1)
         {
             result = nodes.Select(n => n.HasElements ? (object)new DynamicXml(n) : n.Value).ToList();
             return true;
         }
         
    
         XElement node = _root.Element(binder.Name);
         if (node != null)
         {
             result = node.HasElements || node.HasAttributes ? (object)new DynamicXml(node) : node.Value;
             return true;
         }
    
         return true;
     }
 }

I write the comment for the specific value and you can have a look.

Updated code:

  foreach (var host in namelist)
             {
                 foreach (var inter in host.interfaces.@interface)
                 {
                     Console.WriteLine(inter.ip);    //Get ip
                 }
             }

The result is

124607-image.png


If the response is helpful, please click "Accept Answer" and upvote it.


Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.









image.png (1.1 KiB)
image.png (8.1 KiB)
· 6
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


Hi JackJJun-MSFT,
i have only attached a sample in the question with just one host, but in reality there are multiple hosts (say 100) through which i will have to loop and get the value of each one of them. This failed when i tried with the code you have provided.

The values that i currently need are:
name
ip
model_name

Can you please let me know if there is any way that i can loop through them and get the required values.
I have attached a new file which contains multiple hosts.

124579-xml-file-with-issue.txt


0 Votes 0 ·

@SAbijith-9493, I have updated my code for it. Note I changed some content of the xml file.

0 Votes 0 ·

Hi JackJJun-MSFT,
The problem is i cant change the 'interface' to 'Interface' in the XML file. This is because the file is generated and not created manually.
Let me give you a bit of background:

We have a website which acts as a monitoring tool. On this website, we add the devices that we need to monitor. On this website, the IP addresses have are to be entered in a field called 'interface'.
This website allows us to export the properties of the device to an XML file. And hence since the XML file is generated automatically by the website, so it will have the field as 'interface' in the XML file. This is the reason i cannot modify 'interface' to 'Interface', nor can i ask any of our customers to modify it.

So is there any solution that can be used to bypass this??

0 Votes 0 ·
Show more comments