0

I am trying to find a way to take an XmlNodeList and Deserialize it.

I will need to take the XmlNodeList obj and make it ready for deserialization by converting it into something that the serializer can use.

Any Advice?

            string fileLoc = @"File.xml";
        XmlDocument xdoc = new XmlDocument();
        xdoc.Load(fileLoc);
        XmlNodeList ndlist = xdoc.SelectNodes("//DConfig/ConfigValue/UrlListValues/UrlInfo");

        UrlListValues myObject;
        XmlSerializer mySerializer = new XmlSerializer(typeof(UrlListValues));
        FileStream myFileStream = new FileStream(fileLoc, FileMode.Open);

        // *** This is where the problem starts. Cannot cast as UrlListValues
        myObject = (UrlListValues)mySerializer.Deserialize(myFileStream);

        foreach (UrlInfo xn in myObject)
        {
            // Do stuff
        }
Michael Meritt
  • 383
  • 5
  • 18

2 Answers2

5

You'll have to select the parent node and deserialize that. For you it would probably be something like this:

XmlNode node= xdoc.SelectSingleNode("//DConfig/ConfigValue/UrlListValues");
XmlSerializer ser = new XmlSerializer(typeof(UrlListValues));
var deser = (UrlListValues)ser.Deserialize(new StringReader(node.OuterXml));

This could be done using XDocument as well, using something like:

string fileLoc = @"File.xml";
XDocument xdoc = XDocument.Load(fileLoc);
XmlSerializer mySerializer = new XmlSerializer(typeof(UrlListValues));
XElement urlListValuesEl = xdoc.Root.Descendants("UrlListValues").First();
myObject = (UrlListValues)mySerializer.Deserialize(urlListValuesEl.CreateReader());

(edit) One other thought - you could pretty easily doing this just using XmlReader directly:

myObject myobj = null;
using(XmlReader reader = XmlReader.Create(fileLoc))
{
    if (reader.ReadToFollowing("UrlListValues")
    {
        XmlSerializer ser = new XmlSerializer(typeof(UrlListValues));
        myobj = (UrlListValues)ser.Deserialize(reader.ReadSubTree());
    }
    else
    {
        throw Exception("Failed to find node");
    }
}
Dan Field
  • 20,885
  • 5
  • 55
  • 71
1

In my practice I found that working with XmlDocument class is very awkward. I would suggest to use a 'newer' implementation called XDocument.

So the solution might look like this :

var doc = XDocument.Parse("myFile.xml");
var uris = doc.Element("root").Elements("Cars").Select(p =>
    new UrlListValues
    {
        Name = p.Attribute("Name"),
        URL = p.Element("URL")
    });

Here are some additional samples how to use XDocument class Parse xml using LINQ to XML to class objects

Community
  • 1
  • 1
Marty
  • 3,485
  • 8
  • 38
  • 69
  • this is fine, but would lose the benefits of using `XmlSerializer` - the entity might be far more complicated than just two attributes/elements, and this code would need to be synced up for any changes to the class(es). – Dan Field Jan 21 '16 at 23:16
  • As Dan mentioned - there's nothing stopping You from using XmlDserializer inside on that select statement – Marty Jan 22 '16 at 00:10