Reputation: 385
My goal is to extract the data from the XML. But I have some rather complex XML that is not easily converted to C sharp classes.
The XML looks like this:
<group.........>
<suite....>
<properties>
<property name=....../>
</properties>
<suite type="test">
<suite type="test1">
<suite...>
<suite...>
<suite...>
<case id="1000" name="example">
<properties>
<property ...../>
</properties>
</case>
<case.......>
<properties>
<property ...../>
</properties>
</case>
<case>
<properties>
<property .... />
</properties>
</case>
</suite>
</suite>
</suite>
</suite>
</suite>
</suite>
</group>
I have used an online xml to c sharp convert to create classes, but it does not seem to handle the XML structure correctly.
Update:
The XML comes from NUNIT3. It is the result of the UNIT3 console that is written to an XML document.
Update 2:
I am able to extract data using below code - don't know if there is a more elegant solution:
XElement resultFile = XElement.Load($"{resultFilePathList}");
var dataFromXML = (
from data in resultFile.Descendants("case")
select new
{
caseid = data.Attribute("id").Value,
name = data.Attribute("fullname").Value,
result = data.Attribute("result").Value,
duration = data.Attribute("duration").Value
}
);
Upvotes: 1
Views: 1477
Reputation: 2156
Check this code, is as simple as this
using System.Xml.Serialization;
using System.IO;
.......
StreamReader streamer = new StreamReader("yourgroup.xml");
XmlSerializer serializer = new XmlSerializer(typeof(group));
group x = (group)serializer.Deserialize(streamer);
streamer.Close();
And you have do define your classes, somehow like this
public class group {List<suite> suite;}
public class suite
{
public List<suite> suite;
public List<property> properties;
}
Ok, you can add additional annotation if you need specific handling For instance if there is "case" element, create your class with different name
public class xcase
{
public String id;
public String name;
public Property[] properties;...
}
public class suite
{
[XmlElement(ElementName = "case")]
public xcase[] cases {get; set; }
....
}
Upvotes: 1
Reputation: 34421
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication120
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement group = doc.Root;
Suite rootSuite = new Suite();
Suite.ReadXml(group, rootSuite);
}
}
public class Suite
{
public List<Suite> suites { get; set; }
public List<Case> cases { get; set; }
public Dictionary<string, string> properties { get; set; }
public string type { get; set; }
public static void ReadXml(XElement xparentSuite, Suite parentSuite)
{
foreach (XElement xSuite in xparentSuite.Elements("suite"))
{
parentSuite.type = (string)xSuite.Attribute("type");
if (parentSuite.suites == null) parentSuite.suites = new List<Suite>();
Suite newSuite = new Suite();
parentSuite.suites.Add(newSuite);
XElement properties = xSuite.Element("properties");
if (properties != null)
{
parentSuite.properties = properties.Elements("property")
.GroupBy(x => (string)x.Attribute("name"), y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
parentSuite.cases = xSuite.Elements("case").Select(x => new Case(x)).ToList();
ReadXml(xSuite, newSuite);
}
}
}
public class Case
{
public string id { get; set; }
public string name { get; set; }
public Dictionary<string, string> properties { get; set; }
public Case() { }
public Case(XElement _case)
{
id = (string)_case.Attribute("id");
name = (string)_case.Attribute("name");
properties = _case.Descendants("property")
.GroupBy(x => (string)x.Attribute("name"), y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}
Upvotes: 1