How to do the pagination with XmlReader class c# - c#

At present i am fetching data from xml file using LINQ but the problem is i am using XDocument to load xml file but XDocument class load xml data into memory. so if there is 10,000 data in my xml file then XDocument class will load 10,000 data into memory. so some one tell me if use read xml data with XmlReader class then it will not dump full data into memory.
At present this way i am fetching data from xml file.
My xml data look like:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Orders>
<OrderID>10248</OrderID>
<CustomerID>VINET</CustomerID>
<EmployeeID>5</EmployeeID>
<OrderDate>1996-07-04T00:00:00</OrderDate>
<RequiredDate>1996-08-01T00:00:00</RequiredDate>
<ShippedDate>1996-07-16T00:00:00</ShippedDate>
<ShipVia>3</ShipVia>
<Freight>32.3800</Freight>
<ShipName>Vins et alcools Chevalier</ShipName>
<ShipAddress>59 rue de l'Abbaye</ShipAddress>
<ShipCity>Reims</ShipCity>
<ShipPostalCode>51100</ShipPostalCode>
<ShipCountry>France</ShipCountry>
</Orders>
</Root>
here i am posting code wich fetch data from xml file with order by and paging.
XDocument document = XDocument.Load(#"c:\users\documents\visual studio 2010\Projects\WindowsFormsApplication5\WindowsFormsApplication5\Orders.xml");
bool isDesc = true;
//setup basic query
var query = from r in document.Descendants("Orders")
select new
{
OrderID = r.Element("OrderID").Value,
CustomerID = r.Element("CustomerID").Value,
EmployeeID = r.Element("EmployeeID").Value,
};
//setup query result ordering,
//assume we have variable to determine ordering mode : bool isDesc = true/false
if (isDesc)
query = query.OrderByDescending(o => o.OrderID);
else
query = query.OrderBy(o => o.OrderID);
//setup pagination,
//f.e displaying result for page 2 where each page displays 100 data
var page = 1;
var pageSize = 5;
query = query.Skip(page - 1 * pageSize).Take(pageSize);
//execute the query to get the actual result
//var items = query.ToList();
dataGridView1.DataSource = query.ToList();
So some one tell me how could i use xmlreader to read data from xml file with pagination and order by clause will be there.
I got one hit but do not understand how to use it for my purpose:
using( var reader = XmlReader.Create( . . . ) )
{
reader.MoveToContent();
reader.ReadToDescendant( "book" );
// skip N <book> elements
for( int i = 0; i < N; ++i )
{
reader.Skip();
reader.ReadToNextSibling( "book" );
}
// read M <book> elements
for( int i = 0; i < M; ++i )
{
var s = reader.ReadOuterXml();
Console.WriteLine( s );
reader.ReadToNextSibling( "book" );
}
}
So please see the above code and help me to construct the code which would use xml reader to fetch paginated data.

Try this code. Your latest posting is locked so I had to answer here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
Order order = new Order();
while(reader.ReadToFollowing("Orders"))
{
string xml = reader.ReadOuterXml().Trim();
XElement element = XElement.Parse(xml);
order.Add(element);
}
order.Sort();
}
}
public class Order
{
public void Add(XElement element)
{
if (orders == null)
{
orders = new List<Order>();
}
Order newOrder = new Order();
newOrder.OrderId = int.Parse(element.Element("OrderID").Value);
newOrder.CustomerId = element.Element("CustomerID").Value;
newOrder.EmployeeId = int.Parse(element.Element("EmployeeID").Value);
newOrder.OrderDate = DateTime.Parse(element.Element("OrderDate").Value);
newOrder.RequiredDate = DateTime.Parse(element.Element("RequiredDate").Value);
newOrder.ShippedDate = DateTime.Parse(element.Element("ShippedDate").Value);
newOrder.ShipVia = int.Parse(element.Element("ShipVia").Value);
newOrder.Freight = double.Parse(element.Element("Freight").Value);
newOrder.ShipName = element.Element("ShipName").Value;
newOrder.ShipAddress = element.Element("ShipAddress").Value;
newOrder.ShipCity = element.Element("ShipCity").Value;
newOrder.ShipPostalCode = int.Parse(element.Element("ShipPostalCode").Value);
newOrder.ShipCountry = element.Element("ShipCountry").Value;
orders.Add(newOrder);
}
public void Sort()
{
orders = orders.OrderBy(x => x.OrderId).ToList();
}
public static List<Order> orders { get; set; }
public int OrderId { get; set; }
public string CustomerId { get; set; }
public int EmployeeId { get; set; }
public DateTime OrderDate { get; set; }
public DateTime RequiredDate { get; set; }
public DateTime ShippedDate { get; set; }
public int ShipVia { get; set; }
public double Freight { get; set; }
public string ShipName { get; set; }
public string ShipAddress { get; set; }
public string ShipCity { get; set; }
public int ShipPostalCode { get; set; }
public string ShipCountry { get; set; }
}
}
​

Related

convert from xml to list c# in .net core

C#:
XElement Xml = null;
var apiResponse = response.Content.ReadAsStringAsync().Result;
Xml = Newtonsoft.Json.JsonConvert.DeserializeObject<XElement>(apiResponse);
XML response from above code:
I'm having errors with Images xml part, while converting it to List,
I tried so many options, Please provide suggestion from below
<root>
<Column1>
<ID>2702</ID>
<Desc>Failed</Desc>
<Address>Florida</Address>
<Date>2019-04-30T23:10:36.79</Date>
<**Images**>
<Image>
<File>1-RRamos.PNG</File>
</Image>
<Image>
<File>RRamos.PNG</File>
</Image>
<Image>
<File>3-RRamos.PNG</File>
</Image>
</**Images**>
</Column1>
</root>
Trying to convert from xml to List from below
public class objClass
{
public string ID{ get; set; }
public string Desc{ get; set; }
public string Address { get; set; }
public DateTime? Date{ get; set; }
//public string[] ImageFileNames { get; set; }
public List<Images> FileName { get; set; }
}
public class FileName
{
public string File{ get; set; }
}
List<objClass> list = Xml.Elements("ID").Select(sv => new objClass()
{
ID= (string)sv.Element("ID"),
Desc= (string)sv.Element("Desc"),
Address = (string)sv.Element("Address"),
Date= (DateTime?)sv.Element("Date"),
//**,Images = (List)sv.Element("Images")**
}).ToList();
From XML response, trying to convert it to List.
You can't use the Newtonsoft.Json library to deserialize from an XML.
Solution 1: Convert XML to list via XPath
Parse XML string to XDocument.
With XPath: "//root/Column1", select the <Column1> element.
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using System.Xml.XPath;
var apiResponse = await response.Content.ReadAsStringAsync();
XDocument #Xml = XDocument.Parse(apiResponse);
List<ObjClass> list = #Xml.XPathSelectElements("//root/Column1")
.Select(sv => new ObjClass()
{
ID = (string)sv.Element("ID"),
Desc = (string)sv.Element("Desc"),
Address = (string)sv.Element("Address"),
Date = (DateTime?)sv.Element("Date"),
Images = sv.Element("Images")
.Elements("Image")
.Select(x => new Image
{
File = (string)x.Element("File")
})
.ToList()
})
.ToList();
Solution 2: Deserialize XML
This answer will be a bit complex but work the same as Solution 1.
Write the apiResponse value into MemoryStream.
Deserialize the MemoryStream via XmlSerializer as Root.
Extract root.Column and add into list.
[XmlRoot(ElementName = "root")]
public class Root
{
[XmlElement("Column 1")]
public ObjClass Column { get; set; }
}
public class ObjClass
{
public string ID { get; set; }
public string Desc { get; set; }
public string Address { get; set; }
public DateTime? Date { get; set; }
[XmlArray]
[XmlArrayItem(typeof(Image), ElementName = "Image")]
public List<Image> Images { get; set; }
}
public class Image
{
public string File { get; set; }
}
using System.Xml;
using System.Xml.Serialization;
using System.IO;
var apiResponse = await response.Content.ReadAsStringAsync();
using var stream = new MemoryStream();
using var writer = new StreamWriter(stream);
writer.Write(apiResponse);
writer.Flush();
stream.Position = 0;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Root));
Root root = (Root)xmlSerializer.Deserialize(stream);
List<ObjClass> list = new List<ObjClass>();
list.Add(root.Column);
Concern:
Use await instead of Task<T>.Result as Task<T>.Result will block the calling thread until it (the task) is completed. With await, the task is waited to be completed asynchronously. Reference: What is the difference between await Task and Task.Result?
public class objClass
{
public string ID { get; set; }
public string Desc { get; set; }
public string Address { get; set; }
public DateTime? Date { get; set; }
public string[] ImageFileNames { get; set; }
}
var list = Xml.Elements("root").Elements("Column1")
.Select(sv => new objClass()
{
ID = (string)sv.Element("ID"),
Desc = (string)sv.Element("Desc"),
Address = (string)sv.Element("Address"),
Date = (DateTime?)sv.Element("Date"),
ImageFileNames = sv.Element("Images")
.Elements("Image")
.Select(i => (string)i.Element("File"))
.ToArray(),
})
.ToList();

Creating a XML file from a database with a model C#

So I need to create a method that makes an XML file from a database, I have already written the stored procedures that get the information from a database for the XML now I only need to write the part where I convert my database to a XML file using the properties of another class that I have written as nodes.
public string CreateXML(Object YourClassObject){
XmlDocument xmlDoc =new XmlDocument(); //Represents an XML document,
// Initializes a new instance of the XmlDocument class.
XmlSerializer xmlSerializer = new XmlSerializer(YourClassObject.GetType());
// Creates a stream whose backing store is memory.
using (MemoryStream xmlStream =new MemoryStream())
{
xmlSerializer.Serialize(xmlStream, YourClassObject);
xmlStream.Position = 0;
//Loads the XML document from the specified string.
xmlDoc.Load(xmlStream);
return xmlDoc.InnerXml;
}
}
This is some code I found online I think I can use for serializing my model, but i'm accessing the database over an event that I created (I'll provide the code tomorrow when I get to work). Anyway I'm accesing the database in the event like the following e.DataTable. Any ideas anybody?
My model looks like the following:
public class DataModel
{
string Sifra {get; set;}
public string Naziv {get; set;}
public string JM {get; set;}
public int Kolicina {get; set;}
public float Cena_x0020_vp {get; set;}
public float Cena_x0020_mp {get; set;}
public float Cena_x0020_bod {get; set;}
public string Slika {get; set;}
public string Grupa {get; set;}
}
This is a sample of how my generated XML should look like.
<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2019-04-17T19:13:54">
<row>
<Sifra>ADA110-100</Sifra>
<Naziv_x0020_artikla>Adapter 220/110VAC 100W</Naziv_x0020_artikla>
<JM>kom</JM>
<Kolicina>1</Kolicina>
<Cena_x0020_vp>2683.33</Cena_x0020_vp>
<Cena_x0020_mp>3220</Cena_x0020_mp>
<Cena_x0020_bod>28</Cena_x0020_bod>
<Slika1> ada110v.jpg</Slika1>
<Grupa>Adateri 110V AC</Grupa>
</row>
Problem solved:
private void CreateXML(DataTable dataTable)
{
var list = new List<Row>();
XmlSerializer writer = new XmlSerializer(typeof(List<Row>));
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\ExportZaWeb.xml";
FileStream file = File.Create(path);
foreach (DataRow row in dataTable.Rows)
{
Row r = new Row();
r.Naziv = row["Naziv Artikla"].ToString();
r.JM = row["JM"].ToString();
r.Kolicina = row["Kolicina"].ToString();
r.Cena_x0020_vp = row["Cena vp"].ToString();
r.Cena_x0020_mp = row["Cena mp"].ToString();
r.Cena_x0020_bod = row["Cena bod"].ToString();
r.Slika = row["Slika1"].ToString();
r.Grupa = row["Grupa"].ToString();
list.Add(r);
}
writer.Serialize(file, list);
file.Close();
}
Why not let the stored procedure return the xml for you. The query in the stored procedure would lool something like this:
SELECT Sifra, Naziv, JM, Kolicina, Cena_x0020_vp, Cena_x0020_mp, Cena_x0020_bod, Slika, Grupa
FROM DataModel
FOR XML AUTO
Create a method which takes in a list or IEnumerable object of the Models and returns a string containing the XML (untested, but should get you started), this is assuming you already have the database data in usable objects:
public string GetXmlForModels(IEnumerable<DataModel> dataModels)
{
//Assume a list of DataModels is in dataModels of type IEnumerable<DataModel>
var doc = new XmlDocument();
foreach (var model in dataModels)
{
var row = (XmlElement)doc.AppendChild(doc.CreateElement("row"));
row.SetAttribute("xmlns:od", "urn:schemas-microsoft-com:officedat");
row.SetAttribute("generated", DateTime.Now.ToString("yy-MM-ddTHH:mm:ss"));
var sifraElement = doc.CreateElement("Sifra");
sifraElement.InnerText = model.Sifra;
row.AppendChild(sifraElement);
//Repeat top 3 lines for each element ...
doc.AppendChild(row);
}
return doc.OuterXml;
}
Use XML Serializer :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication110
{
class Program
{
const string INPUT_FILENAME = #"c:\temp\test.xml";
const string OUTPUT_FILENAME = #"c:\temp\test1.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(INPUT_FILENAME);
string xml = reader.ToString();
XmlSerializer serializer = new XmlSerializer(typeof(DataRoot));
DataRoot root = (DataRoot)serializer.Deserialize(reader);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
XmlWriter writer = XmlWriter.Create(OUTPUT_FILENAME,settings);
serializer.Serialize(writer, root);
}
}
[XmlRoot(ElementName = "dataroot", Namespace = "")]
public class DataRoot
{
[XmlElement(ElementName = "row", Namespace = "")]
public List<DataModel> rows { get; set; }
}
[XmlRoot(ElementName = "row", Namespace = "")]
public class DataModel
{
string Sifra { get; set; }
public string Naziv { get; set; }
public string JM { get; set; }
public int Kolicina { get; set; }
public float Cena_x0020_vp { get; set; }
public float Cena_x0020_mp { get; set; }
public float Cena_x0020_bod { get; set; }
public string Slika { get; set; }
public string Grupa { get; set; }
}
}

Parse XML data with Multiple List & Class objects using LINQ-To-XML in C#

Let's say I want to parse following XML file:
<EmployeeDetails>
<Employee> //List of Employees
<Id>11</Id>
<name>a</name>
<Dependents> //List of Dependents of a single employee
<Dependent>
<name>a1</name>
<age>50</age>
</Dependent>
<Dependent>
<name>a2</name>
<age>52</age>
</Dependent>
</Dependents>
<Department> //Unique per Emp
<DeptId>1</DeptId>
<DeptName>D1</DeptName>
</Department>
</Employee>
<Employee>
-----
--------
</Employee>
</EmployeeDetails>
Following is the Class Structure for above file:
public class Employee
{
public int id {get; set;}
public string name {get; set;}
public List<Dependents> Dependents {get; set;}
public Department Department {get; set;}
}
public class Dependents
{
public string name {get; set;}
public int age {get; set;}
}
public class Department
{
public int DeptId {get; set;}
public string DeptName {get; set;}
}
Now, I want to parse above XML structure and I am able to do it for id and name of Employee but I am unable to parse further.
Let me show you what I've done so far :
public static void ParseXml()
{
string xmldoc = //let's assume I've data in this string
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(xmldoc);
var query = from d in xdoc.Root.Descendants("Employee")
select d;
List<Employee> lsEmp = new List<Employee>();
foreach (var q in query)
{
Employee obj = new Employee();
obj.Id = Convert.ToInt32(q.Element("Id").Value);
obj.name = q.Element("name").Value;
obj.Department = new Department();
obj.Dependents = new List<Dependents>();
// how to get data further?
lsEmp.Add(obj);
}
So I need help in order to parse XML data from these list of Dependents and Department object.
Following your own structure, here's the way to continue parsing the data you need.
// how to get data further?
var allDependents = q.Elements("Dependents").Elements("Dependent");
foreach (var b in allDependents)
{
Dependents d = new Dependents
{
age = Convert.ToInt32(b.Element("age").Value),
name = b.Element("name").Value
};
obj.Dependents.Add(d);
}
obj.Department.DeptId = Convert.ToInt32(q.Element("Department").Element("DeptId").Value);
obj.Department.DeptName = q.Element("Department").Element("DeptName").Value;
Notice that I have used .Elements("") to get all the child nodes under Dependents
Here is code using just linq and no for loops
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
string xml = File.ReadAllText(FILENAME);
ParseXml(xml);
}
public static void ParseXml(string xml)
{
XDocument xdoc = XDocument.Parse(xml);
List<Employee> employees = xdoc.Descendants("Employee").Select(x => new Employee () {
id = (int)x.Element("Id"),
name = (string)x.Element("Name"),
Department = x.Elements("Department").Select(y => new Department() { DeptId = (int)y.Element("DeptId"), DeptName = (string)y.Element("DeptName")}).FirstOrDefault(),
Dependents = x.Descendants("Dependent").Select(y => new Dependents() { age = (int)y.Element("age"), name = (string)y.Element("name")}).ToList()
}).ToList();
}
}
public class Employee
{
public int id { get; set; }
public string name { get; set; }
public List<Dependents> Dependents { get; set; }
public Department Department { get; set; }
}
public class Dependents
{
public string name { get; set; }
public int age { get; set; }
}
public class Department
{
public int DeptId { get; set; }
public string DeptName { get; set; }
}
}
Maybe this can help you:
XDocument xdoc = new XDocument();
xdoc = XDocument.Parse(xmldoc);
var query = from d in xdoc.Root.Descendants("Employee")
select d;
List<Employee> lsEmp = new List<Employee>();
foreach (var q in query)
{
Employee obj = new Employee();
obj.Id = Convert.ToInt32(q.Element("Id").Value);
obj.name = q.Element("name").Value;
obj.Department = new Department()
{
DeptName = q.Element("Department").Element("name").Value,
DeptId =
Convert.ToInt32(q.Element("Department").Element("age").Value)
};
obj.Dependents = new List<Dependents>();
foreach (var e in q.Element("Dependents").Elements("Dependent"))
{
var dependent = new Dependents()
{
name = e.Element("name").Value,
age = Convert.ToInt32(e.Element("age").Value)
};
obj.Dependents.Add(dependent);
}
lsEmp.Add(obj);
}

Convert embedded XML to List<T> within a Repository

I have a situation where in I have to read my master data from XML files.
Hence I have created a Repository which looks like this.
public class XmlReadRepository<T> : IReadRepository<T> where T : class, new()
{
private IEnumerable<T> _data { get; set; }
private IQueryable<T> _query { get; set; }
public XmlReadRepository()
{
Type t = typeof(T);
//Load _data from xml
}
public IQueryable<T> All()
{
return _query;
}
public IQueryable<T> Get(System.Linq.Expressions.Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "")
{
throw new NotImplementedException();
}
}
I have exported all my SQL database data into XML file using below SQL query
SELECT *
FROM Company
FOR XML RAW, ROOT('Company')
Whose outputs comes as below
<Company>
<row Id="1" Name="ABC" StartDate="2000-03-01" />
<row Id="2" Name="XYZ" StartDate="2001-13-11" />
</Company>
The xml is physically saved to a file and is embedded as a resource.
Now I am looking for some fast way to serialize the xml data into list.
I have tried loading the xml file with stream and then using reflection created objects by iterating through the XML. Is there any better way by which I can serialize the xml data to my C# object.
Also please share your inputs on whether is it good to have xml as an embedded resource as the size of each xml can be around 8MB and there are 5 such XMLs.
You can turn my code into a function
public class Row
{
private static XmlTextReader reader = null;
public int Id { get; set; }
public string name { get; set; }
public DateTime startDate { get; set; }
public Row() { }
public Row(TextReader sReader)
{
reader = new XmlTextReader(sReader); //can be filename instead of stringreader
}
public Row Get(string elementName)
{
Row results = null;
if (!reader.EOF)
{
if (reader.Name != elementName)
{
reader.ReadToFollowing(elementName);
}
if (!reader.EOF)
{
XElement newRow = (XElement)XElement.ReadFrom(reader);
results = new Row() { Id = (int)newRow.Attribute("Id"), name = (string)newRow.Attribute("Name"), startDate = (DateTime)newRow.Attribute("StartDate") };
}
}
return results;
}
}​
Use xml linq like below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<Company>" +
"<row Id=\"1\" Name=\"ABC\" StartDate=\"2000-03-01\" />" +
"<row Id=\"2\" Name=\"XYZ\" StartDate=\"2001-13-11\" />" +
"</Company>";
XDocument doc = XDocument.Parse(xml); // use Load to read from file
var rows = doc.Descendants("row").Select(x => new
{
id = (int)x.Attribute("Id"),
name = (string)x.Attribute("Name"),
startDate = (DateTime)x.Attribute("StartDate")
}).ToList();
//using xmltextreader
List<Row> rows2 = new List<Row>();
StringReader sReader = new StringReader(xml);
XmlTextReader reader = new XmlTextReader(sReader); //can be filename instead of stringreader
while(!reader.EOF)
{
if (reader.Name != "row")
{
reader.ReadToFollowing("row");
}
if (!reader.EOF)
{
XElement newRow = (XElement)XElement.ReadFrom(reader);
rows2.Add(new Row() { Id = (int)newRow.Attribute("Id"), name = (string)newRow.Attribute("Name"), startDate = (DateTime)newRow.Attribute("StartDate") });
}
}
}
}
public class Row
{
public int Id { get; set; }
public string name { get; set; }
public DateTime startDate { get; set; }
}
}
​

XML Parsing to c# objects

I am trying to do a XML parser which will extract data from a website using REST service, the protocol for communication is HTTP, the data I get is in XML format, and I get to the data I need after several requests to different addresses on the server. I need to parse this data to c# objects so I can operate with them lately.
The information on the server is on 5 levels( I am willing to make work only 4 of them for know)
1-List of vendors
2-List of groups
3-List of subgroups
4-List of products
5-List of full information about products
After I get to 4th level I need to check if the product is in my database or if it has different details so I can add or update it.
With "GET" request to a server I get XML with this structure:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<vendors>
<vendor>
<id>someID</id>
<name>someName</name>
</vendor>
<vendor>
<id>someId1</id>
<name>somename1</name>
</vendor>
</vendors>
XML structure for groups is the same :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<groups vendor_id="43153185318">
<group>
<id>someID</id>
<name>someName</name>
</group>
<group>
<id>someId1</id>
<name>somename1</name>
</group>
The XML structure is analogical for subgroups and products, except that for products I have more elements like catalog_num, price etc.
I made the classes as follows :
public class VendorList
{
public List<Vendor> vendor_list { get; set; }
public VendorList()
{
vendor_list = new List<Vendor>();
}
}
public class Vendor
{
public string id { get; set; }
public string name { get; set; }
public List<Group> groups_list { get; set; }
public Vendor()
{
id = "N/A";
name = "N/A";
groups_list = new List<Group>();
}
}
public class Group
{
public string id { get; set; }
public string name { get; set; }
public List<SubGroup> subgroup_list { get; set; }
public Group()
{
id = "N/A";
name = "N/A";
subgroup_list = new List<SubGroup>();
}
}
public class SubGroup
{
public string id { get; set; }
public string name { get; set; }
public List<Product> product_list { get; set; }
public SubGroup()
{
id = "N/A";
name = "N/A";
product_list = new List<Product>();
}
}
public class Product
{
public string available { get; set; }
public string catalog_num { get; set; }
public string code { get; set; }
public string currency { get; set; }
public string description { get; set; }
public string haracteristics { get; set; }
public string product_id { get; set; }
public string model { get; set; }
public string name { get; set; }
public string price { get; set; }
public string price_dds { get; set; }
public string picture_url { get; set; }
public Product()
{
available = "N/A";
catalog_num = "N/A";
code = "N/A";
currency = "N/A";
description = "N/A";
haracteristics = "N/A";
product_id = "N/A";
model = "N/A";
name = "N/A";
price = "N/A";
price_dds = "N/A";
picture_url = "N/A";
}
}
and the Parser method like this :
public static void FillVendor(string url)
{
string result = GetXMLstream(url);
var vendors = new VendorList();
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(result));
doc.Save(#"D:/proba/proba.xml");
XDocument d = XDocument.Load(#"D:/proba/proba.xml");
vendors.vendor_list = (from c in d.Descendants("vendor")
select new Vendor()
{
id = c.Element("id").Value,
name = c.Element("name").Value
}).ToList<Vendor>();
foreach (Vendor v in vendors.vendor_list)
{
FillGroups(v.id);
}
}
public static void FillGroups(string vendorID)
{
string url = "main address" + vendorID;
string result = GetXMLstream(url);
var group = new Vendor();
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(result));
doc.Save(#"D:/proba/proba1.xml");
XDocument d = XDocument.Load(#"D:/proba/proba1.xml");
group.groups_list = (from g in d.Descendants("group")
select new Group()
{
id = g.Element("id").Value,
name = g.Element("name").Value
}).ToList<Group>();
foreach (Group g in group.groups_list)
{
FillSubGroup(vendorID, g.id);
}
}
public static void FillSubGroup(string vendorID, string groupID)
{
string url = "main address" + vendorID+"/"+groupID;
string result = GetXMLstream(url);
var subgroup = new Group();
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(result));
doc.Save(#"D:/proba/proba2.xml");
XDocument d = XDocument.Load(#"D:/proba/proba2.xml");
subgroup.subgroup_list = (from g in d.Descendants("subgroup")
select new SubGroup()
{
id = g.Element("id").Value,
name = g.Element("name").Value
}).ToList<SubGroup>();
foreach (SubGroup sb in subgroup.subgroup_list)
{
FillProduct(vendorID, groupID, sb.id);
}
}
public static void FillProduct(string vendorID,string groupID,string subgroupID)
{
string url = "main address" + vendorID + "/" + groupID+"/"+subgroupID;
string result = GetXMLstream(url);
var product = new SubGroup();
XmlDocument doc = new XmlDocument();
doc.Load(new StringReader(result));
doc.Save(#"D:/proba/proba2.xml");
XDocument d = XDocument.Load(#"D:/proba/proba2.xml");
product.product_list = (from g in d.Descendants("subgroup")
select new Product()
{
available = g.Element("available").Value,
catalog_num = g.Element("catalog_num").Value,
code = g.Element("code").Value,
currency = g.Element("currency").Value,
description = g.Element("description").Value,
haracteristics = g.Element("haracteristics").Value,
product_id = g.Element("id").Value,
model = g.Element("model").Value,
name = g.Element("name").Value,
price = g.Element("price").Value,
price_dds = g.Element("price_dds").Value,
picture_url = g.Element("small_picture").Value,
}).ToList<Product>();
}
But after finishing parsing I try to check if my Lists are populated with objects, but I get an error which says that they are null "NullReferenceException"
So my question is did I make classes properly and is my parsing method right ( you can suggest how to parse the xml without creating a file on my computer) and if I didn't where is my mistake and how should I make it work properly?
Thanks in advance!
modify this line add 's'( vendor -> vendors)
-> vendors.vendor_list = (from c in d.Descendants("vendor")
and the same case for group -> groups
Instead of making the classes yourself.
Create a properly formatted XML Schema either manually or with Visual Studio and then from that XSD File you've created generate your C# Classes.

Categories

Resources