0

I need to parse a xml document into object models that I've created but I can't figure out how to do so, I think it's because of my lack of understanding of the xml structure.

I've tried to get all the elements from the document and to create individual object from each based on their attributes I think they're called.

Here is my C# code :

var manifest = XDocument.Load(theDocument);
var allTheElements = manifest.Descendants();

foreach (var element in allTheElements)
{
     //No idea how to parse each object into individual ManifestModel's
}

public class ManifestModel
{
    public string Version { get; set; }
    public string Resource { get; set; }
    public string Size { get; set; }
    public string Checksum { get; set; }
}

And here is the XML data :

<?xml version="1.0" encoding="UTF-8"?>
<manifest version="1.0.0" totalbytes="6131797">
  <source uri="codeapi.io/Game/patches/">
    <file resource="FooGame.sln" size="1125" checksum="530B9F1C2412A6D74EF017919074FD8966E5280D" />
    <file resource=".vs\FooGame\v16\.suo" size="69120" checksum="438976A3681FDD503DB4FBFCBB5D420E9E8838DD" />
  </source>
</manifest>
taktak
  • 90
  • 10
John V Dole
  • 321
  • 1
  • 3
  • 11
  • 2
    Possible duplicate of [Getting attribute value of an XML Document using C#](https://stackoverflow.com/questions/3750678/getting-attribute-value-of-an-xml-document-using-c-sharp) – FeRaaC Jul 31 '19 at 14:36
  • Would that work to get the version number as well? – John V Dole Jul 31 '19 at 14:37
  • 1
    Hello, take a look on this : [tutorial XDocument](https://www.c-sharpcorner.com/article/reading-and-writing-xml-using-xlinq/). This should help you – taktak Jul 31 '19 at 14:38
  • 1
    https://stackoverflow.com/questions/18017692/c-sharp-get-values-from-xml-attributes look at this. Linq is probably you best option – BmoreDude Jul 31 '19 at 14:38

3 Answers3

1

Just like we have json2csharp for JSON, we have Xml2Csharp for XML. There are probably lots of other sites that will do this.

Paste your XML and it generates this:

    [XmlRoot(ElementName="file")]
    public class File {
        [XmlAttribute(AttributeName="resource")]
        public string Resource { get; set; }
        [XmlAttribute(AttributeName="size")]
        public string Size { get; set; }
        [XmlAttribute(AttributeName="checksum")]
        public string Checksum { get; set; }
    }

    [XmlRoot(ElementName="source")]
    public class Source {
        [XmlElement(ElementName="file")]
        public List<File> File { get; set; }
        [XmlAttribute(AttributeName="uri")]
        public string Uri { get; set; }
    }

    [XmlRoot(ElementName="manifest")]
    public class Manifest {
        [XmlElement(ElementName="source")]
        public Source Source { get; set; }
        [XmlAttribute(AttributeName="version")]
        public string Version { get; set; }
        [XmlAttribute(AttributeName="totalbytes")]
        public string Totalbytes { get; set; }
    }

One could call that lazy or cheating, but I don't see the point in writing code that can be generated for me in a second. You might not always get perfect results, but it's a good starting point. For example, it uses string for all attribute types. If you're expecting all numeric values you could replace those with int or long.

Now you can deserialize like this:

var serializer = new XmlSerializer(typeof(Manifest), new XmlRootAttribute("manifest"));
using (var stream = System.IO.File.OpenRead("test.xml"))
{
    var deserialized = (Manifest)serializer.Deserialize(stream);
}

Once you've got the data deserialized into something, the rest is much easier. You can either use the auto-generated models or map them to your own.

Scott Hannen
  • 27,588
  • 3
  • 45
  • 62
0

I spent a lot of time working on a similar app that parsed through XML Schema, and I found the easiest way is to turn the XML Document into an XmlNodeList. From here you can use the SelectNodes and SelectSingleNodes to navigate through it. Take a look at this:https://learn.microsoft.com/en-us/dotnet/api/system.xml.xmlnode.selectnodes?view=netframework-4.8, but basically what you do is create an xpath string which selects the node you need. Here is some documentation on that: https://learn.microsoft.com/en-us/dotnet/standard/data/xml/select-nodes-using-xpath-navigation

Max
  • 13
  • 5
0

Using LINQ...

c#

void Main()
{
    string fileName = @"e:\Temp\GamePatches.xml";

    XDocument manifest = XDocument.Load(fileName);
    string version = manifest.Root.Attribute("version").Value;

    List<ManifestModel> manifestModel = new List<ManifestModel>();

    foreach (XElement e in manifest.Descendants("file"))
    {
        manifestModel.Add(new ManifestModel() { Version = version
                , Resource = (string)e.Attribute("resource").Value 
                , Size = (string)e.Attribute("size").Value 
                , Checksum = (string)e.Attribute("checksum").Value }
                );
    }
}

// Define other methods and classes here
public class ManifestModel
{
    public string Version { get; set; }
    public string Resource { get; set; }
    public string Size { get; set; }
    public string Checksum { get; set; }
}
Yitzhak Khabinsky
  • 18,471
  • 2
  • 15
  • 21