0

Aim: - Deserialize data from an xml document and storing it as an array. - Avoiding manually assigning the data to different strings. - The xml document will be manually generated

public void DeserializeObject(string filename)
       {
           try
           {
               XmlSerializer deserializer = new XmlSerializer(typeof(string[]));
               FileStream fs = new FileStream(filename, FileMode.Open);
               string[] XmlData = (string[])deserializer.Deserialize(fs);

               foreach (string p in XmlData)
               {
                   Console.WriteLine(p);
               }
           }
           catch (Exception e)
           {
               Console.WriteLine(e.Message);
           }   
       }

The XML document is as follows

<?xml version="1.0" encoding="utf-8"?>
<Mapping xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Products>
    <Product>
      <software>Seiko</software>
    </Product>
    <Product>
      <hardware>Martina</hardware>
    </Product>
  </Products>
</Mapping>
Jerry Mbawa
  • 59
  • 1
  • 1
  • 12
  • Well your XML file isn't a string array - it's a serialized form of a `List` or something similar... – Jon Skeet Jul 28 '15 at 09:21
  • You have set the serializer to be a type of string[]. The resulting deserialized xml will not be a string array. It will be a object of type Mapping containing a Products object containing an array of Product objects etc. You need to build your class. – CathalMF Jul 28 '15 at 09:23
  • How can I best make it an array XML – Jerry Mbawa Jul 28 '15 at 09:24
  • @JerryMbawa XML cannot just be an array. There must be an enclosing type. – CathalMF Jul 28 '15 at 09:27
  • If you are using .Net framework 4.5 you can generate a type from xml as explained here. https://msdn.microsoft.com/en-us/library/hh371548(v=vs.110).aspx Open a code file where the proxy is to be used. This file should be part of a .NET Framework 4.5 project. Place the cursor in a location in the file outside any existing classes. Select Edit, Paste Special, Paste XML as Classes. After generating the type from xml you can use it to deserialize your xml – Sujith C Nair Jul 28 '15 at 09:39

4 Answers4

1

Try this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication38
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
            "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
            "<Mapping xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
              "<Products>" +
                "<Product>" +
                  "<software>Seiko</software>" +
                "</Product>" +
                "<Product>" +
                  "<hardware>Martina</hardware>" +
                "</Product>" +
              "</Products>" +
            "</Mapping>";

            XDocument doc = XDocument.Parse(input);

            var results = doc.Descendants("Product").Select(x =>
                x.Elements().Select(y => new { type = y.Name, value = (string)y }).ToList()
            ).SelectMany(z => z).ToList();

            var groups = results.GroupBy(x => x.type).ToList();
        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Products are variable, they will be manually added, so it will not be good to define the product elements in the application, reason I wanted an array of the products – Jerry Mbawa Jul 28 '15 at 10:05
  • Will the product (ie hardware Martina) always be the first child after Product tag? – jdweng Jul 28 '15 at 10:45
  • no, it could be anything, and could even change from hardware to (download Martina), so all the products elements are subject to change and they could be more than 2 products at a time – Jerry Mbawa Jul 28 '15 at 10:49
1

Thank you, found this solution

<?xml version="1.0" encoding="utf-8" ?>
<Locations>
  <Location Name="Location1" IP="127.0.0.1"></Location>
  <Location Name="Location2" IP="127.0.0.1"></Location>
  <Location Name="Location3" IP="127.0.0.1"></Location>
  <Location Name="Location4" IP="127.0.0.1"></Location>
  <Location Name="Location5" IP="127.0.0.1"></Location>
</Locations>


using System.Xml.Linq;

class Program
   {
       static void Main(string[] args)
       {
           string[] strarr = GetStringArray("Locations.xml");

           foreach (string str in strarr)
           {
               Console.WriteLine(str);
           }
       }

       public static string[] GetStringArray(string url)
       {
            XDocument doc = XDocument.Load(url);

           var locations = from l in doc.Descendants("Location")
                           select (string)l.Attribute("Name");

           return locations.ToArray();
       }
   }
Jerry Mbawa
  • 59
  • 1
  • 1
  • 12
0

You need to generate a class from your sample XML. You can use the xsd.exe to generate a .xsd and from that create a .cs file.

The you need to add this type to your XmlSerializer

See this answer: Generate C# class from XML

XmlSerializer deserializer = new XmlSerializer(typeof(Mapping)); <- Created class type here.
Community
  • 1
  • 1
CathalMF
  • 9,705
  • 6
  • 70
  • 106
0

If all you want to do is get the data form the XML-document as an array of strings, you can use XmlDocument to load in the data

XmlDocument doc = new XmlDocument();
doc.Load("file.xml");

Then you can find the nodes you need using an xPath expression:

XmlNodeList nodelist = doc.SelectNodes(...);
Ruben Steins
  • 2,782
  • 4
  • 27
  • 48