Extracting detail records of XML via C# LINQ - c#

I have the following XML excerpt. I have no problem extracting the first step of XML but I can't figure out how to get to the second layer and extract each layer. Specifically, the user info in XML below.
Any help will be appreciated...
<?xml version="1.0" encoding="UTF-8" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getStatusReportResponse xmlns:ns2="http://xxxxxxxxx.com/">
<return>
<statusReport>
<record>
<assessorDate />
<assessorOffice />
<availableDate />
<awardDate>01/01/2014</awardDate>
<awardValue>1000000</awardValue>
<businessSector>SYSTEMS</businessSector>
<user>
<accessGrantedDate />
<emailAddress>john.usda#noemail.mil</emailAddress>
<name>JOHN USDA</name>
<phoneNumber>XXX-XXX-XXXX</phoneNumber>
<role>Focal Point</role>
</user>
<user>
<accessGrantedDate />
<emailAddress>john.usda#noemail.mil</emailAddress>
<name>JOHN USDA</name>
<phoneNumber>XXX-XXX-XXXX</phoneNumber>
<role>Focal Point</role>
</user>
</record>
</statusReport>
</return>
</ns2:getStatusReportResponse>
</S:Body>
</S:Envelope>
I've tried this but it only get's me a list of the first user record and not all of them.
var records = from x in xml.Descendants("record")
select new
{
awardDate = (string) x.Descendants("awardDate").FirstOrDefault().Value
,userList = (List<string>) x.Descendants("user").Elements() //.Elements("accessGrantedDate")
.Select(a => a.Value).ToList()
};

I am assuming this is the model of your User class:
public class User
{
public DateTime? AccessGrantedDate { get; set; }
public string EMailAddress { get; set; }
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string Role { get; set; }
}
And this is extracting the User class from the XML:
var records = from x in xml.Descendants("record")
select new
{
AwardDate = (string)x.Element("awardDate"),
UserList = x.Descendants("user").Select(user => new User
{
AccessGrantedDate = string.IsNullOrEmpty((string)user.Element("accessGrantedDate")) ?
(DateTime?) null : DateTime.Parse((string)user.Element("accessGrantedDate")),
EMailAddress = (string)user.Element("emailAddress"),
Name = (string)user.Element("name"),
PhoneNumber = (string)user.Element("phoneNumber"),
Role = (string)user.Element("role")
})
};

As far as I can tell, your code gets the data of all users in the file, but only the values of nodes.
The more organized way to do this would be:
class User
{
public string accessGrantedDate { get; set; }
public string emailAddress { get; set; }
public string name { get; set; }
public string phoneNumber { get; set; }
public string role { get; set; }
}
then:
var records = from x in xml.Descendants("record")
select new
{
awardDate = (string) x.Descendants("awardDate").FirstOrDefault().Value
,userList = x.Descendants("user").Select(a=>new User
{
accessGrantedDate= a.Element("accessGrantedDate").Value,
emailAddress=a.Element("emailAddress").Value,
name=a.Element("name").Value,
phoneNumber=a.Element("phoneNumber").Value,
role = a.Element("role").Value
}).ToList()
};
or, if you don't want to organize your data this way, you may use a list of lists:
var records = from x in xml.Descendants("record")
select new
{
awardDate = (string)x.Descendants("awardDate").FirstOrDefault().Value,
userList = x.Descendants("user").Select(a => a.Elements().Select(b=>b.Value).ToList()).ToList()
};

I solved it by using a 2nd query for detail records, therefore, creating a List as a object inside the outer list.
var records = from x in xml.Descendants("record")
select new
{
awardDate = x.Element("awardDate")
,
userList = from u in x.Descendants("user")
select new
{
accessGrantedDate = (string) u.Element("accessGrantedDate")
,emailAddress =(string) u.Element("emailAddress"
,name = (string) u.Element("name")
,phoneNumber = (string) u.Element("phoneNumber")
,role = (string) u.Element("role")
}
};

Related

C# populating class array from xml linq results in FormatException

I'm getting a FormatException error "Input string was not in a correct format." error...
Employee class is all strings except the Status(int), Type(int) and Displayed(bool)
public partial class Version2 : System.Web.UI.Page {
private Employee[] Employees;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
XDocument xdoc = XDocument.Load(Server.MapPath("~/")+ "V2Employees.xml");
IEnumerable<XElement> emps = xdoc.Root.Descendants();
Employees = emps.Select(x => new Employee()
{
Employee_ID = x.Attribute("id").Value,
First_Name = x.Element("First_Name").Value,
Last_Name = x.Element("Last_Name").Value,
Classification_Group = x.Element("Classification_Group").Value,
Classification_Level = x.Element("Classification_Level").Value,
Postion_Number = x.Element("Postion_Number").Value,
English_Title = x.Element("English_Title").Value,
French_Title = x.Element("French_Title").Value,
Location = x.Element("Location").Value,
Language = x.Element("Language").Value,
Department_ID = x.Element("Department_ID").Value,
Status = int.Parse(x.Element("Status").ToString()),
Type = int.Parse(x.Element("Type").ToString()),
Displayed = false}).ToArray();
}
Example XML going in:
<?xml version="1.0" encoding="utf-8" ?>
<employees>
<employee id="1">
<First_Name>Jane</First_Name>
<Last_Name>Doe</Last_Name>
<Classification_Group>AA</Classification_Group>
<Classification_Level>02</Classification_Level>
<Postion_Number>12345</Postion_Number>
<English_Title>Bob</English_Title>
<French_Title></French_Title>
<Location>Null Island</Location>
<Language>English</Language>
<Department_ID>000001</Department_ID>
<Status>1</Status>
<Type>4</Type>
</employee>
</employees>
By calling ToString on an XElement, you're ending up with the whole element as a string, e.g.
<Status>4</Status>
... and trying to parse that as an int. I would strongly suggest:
Just using the Value property or a cast to string when you want the value of an element as a string (no need for a ToString call afterwards)
Using a cast to int when you want to convert an XElement's value to an integer
I would write your Select as:
// Property names adjusted to .NET naming conventions, type of
// PositionNumber changed to an int.
Employees = emps.Select(x => new Employee
{
EmployeeId = (string) x.Attribute("id"),
FirstName = (string) x.Element("First_Name"),
LastName = (string) x.Element("Last_Name"),
ClassificationGroup = (string) x.Element("Classification_Group"),
ClassificationLevel = (string) x.Element("Classification_Level"),
PositionNumber = (int) x.Element("Postion_Number"),
EnglishTitle = (string) x.Element("English_Title"),
FrenchTitle = (string) x.Element("French_Title"),
Location = (string) x.Element("Location"),
Language = (string) x.Element("Language"),
DepartmentId = (string) x.Element("Department_ID"),
Status = (int) x.Element("Status"),
Type = (int) x.Element("Type"),
Displayed = false
}
You might want to use .Value instead of the cast to string, which will mean you get a NullReferenceException if the element is missing the appropriate sub-element. You may want to use the above form instead, then have a Validate method to check that it has all the required information - that would probably allow you to report errors more clearly:
You could say which property is missing rather than just getting an exception
You could report multiple missing properties in a single error message
See code below. The fix was : xdoc.Root.Descendants("employee"); I also made other improvements
public class Employee
{
static Employee[] Employees = null;
const string FILENAME = #"c:\temp\test.xml";
public static Boolean IsPostBack = false;
string Employee_ID { get; set; }
string First_Name { get; set; }
string Last_Name { get; set; }
string Classification_Group { get; set; }
string Classification_Level { get; set; }
string Postion_Number { get; set; }
string English_Title { get; set; }
string French_Title { get; set; }
string Location { get; set; }
string Language { get; set; }
string Department_ID { get; set; }
int Status { get; set; }
int Type { get; set; }
Boolean Displayed { get; set; }
//protected void Page_Load(object sender, EventArgs e)
public void Page_Load()
{
if (!IsPostBack)
{
XDocument xdoc = XDocument.Load(FILENAME);
IEnumerable<XElement> emps = xdoc.Root.Descendants("employee");
Employees = emps.Select(x => new Employee()
{
Employee_ID = (string)x.Attribute("id"),
First_Name = (string)x.Element("First_Name"),
Last_Name = (string)x.Element("Last_Name"),
Classification_Group = (string)x.Element("Classification_Group"),
Classification_Level = (string)x.Element("Classification_Level"),
Postion_Number = (string)x.Element("Postion_Number"),
English_Title = (string)x.Element("English_Title"),
French_Title = (string)x.Element("French_Title"),
Location = (string)x.Element("Location"),
Language = (string)x.Element("Language"),
Department_ID = (string)x.Element("Department_ID"),
Status = (int)x.Element("Status"),
Type = (int)x.Element("Type"),
Displayed = false
}).ToArray();
}
}
}

How to parse xml with LINQ to an Object with XDocument

I have an xml file as below:
<Message xsi:schemaLocation ="..">
<Header>..</Header>
<Body>
<History
xmlns="..">
<Number></Number>
<Name></Name>
<Item>
<CreateDate>..</CreateDate>
<Type>..</Type>
<Description></Description>
</Item>
<Item>
<CreateDate>..</CreateDate>
<Type>..</Type>
<Description>1..</Description>
<Description>2..</Description>
</Item>
</History>
</Body>
</Message>
I would like to create and object from this as History object.
public class History
{
public string Name { get; set; }
public string Number { get; set; }
public List<Item> Items { get; set; }
}
var xElement = XDocument.Parse(xmlString);
XElement body = (XElement)xElement.Root.LastNode;
XElement historyElement = (XElement)body.LastNode;
var history = new History
{
Name = (string)historyElement.Element("Name"),
Number = (string)historyElement.Element("Number"),
Items = (
from e in historyElement.Elements("Item")
select new Item
{
CraeteDate = DateTime.Parse(e.Element("CreateDate").Value),
Type = (string)e.Element("Type").Value,
Description = string.Join(",",
from p in e.Elements("Description") select (string)p.Element("Description"))
}).ToList()
};
Why this does not work?
The values are always null.
It seems that "historyElement.Element("Name")" is always null even there is an element and value for the element.
Any idea what am I missing?
Thanks
It's due to the namespace, try doing this:
XNamespace ns = "http://schemas.microsoft.com/search/local/ws/rest/v1";// the namespace you have in the history element
var xElement = XDocument.Parse(xmlString);
var history= xElement.Descendants(ns+"History")
.Select(historyElement=>new History{ Name = (string)historyElement.Element(ns+"Name"),
Number = (string)historyElement.Element(ns+"Number"),
Items = (from e in historyElement.Elements(ns+"Item")
select new Item
{
CraeteDate= DateTime.Parse(e.Element(ns+"CreateDate").Value),
Type = (string) e.Element(ns+"Type").Value,
Description= string.Join(",",
from p in e.Elements(ns+"Description") select (string)p)
}).ToList()
}).FirstOrDefault();
If you want to read more about this subject, take a look this link
A couple of minor things here, the xml was malformed here. So had to take a while to test and make it work.
You have an xsi in the front which I assume should be somewhere mentioned in the xsd.
Turns out you have to append the namespace if your xml node has a namespace attached to it as you are parsing the xml tree here:
My sample solution looked like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace ConsoleApplication1
{
public class History
{
public string Name { get; set; }
public string Number { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public DateTime? CreateDate { get; set; }
public string Type { get; set; }
public string Description { get; set; }
}
class Program
{
static void Main(string[] args)
{
string xmlString =
#"<Message>
<Header>..</Header>
<Body>
<History
xmlns=""http://schemas.somewhere.com/types/history"">
<Number>12</Number>
<Name>History Name</Name>
<Item>
<CreateDate></CreateDate>
<Type>Item 1 Type</Type>
<Description>Item 1 Description</Description>
</Item>
<Item>
<CreateDate></CreateDate>
<Type>Item 2 Type</Type>
<Description>Item 2 Description 1</Description>
<Description>Item 2 Description 2</Description>
</Item>
</History>
</Body>
</Message>";
XNamespace ns = "http://schemas.somewhere.com/types/history";
var xElement = XDocument.Parse(xmlString);
var historyObject = xElement.Descendants(ns +"History")
.Select(historyElement => new History
{
Name = historyElement.Element(ns + "Name")?.Value,
Number = historyElement.Element(ns + "Number")?.Value,
Items = historyElement.Elements(ns + "Item").Select(x => new Item()
{
CreateDate = DateTime.Parse(x.Element(ns + "CreateDate")?.Value),
Type = x.Element(ns + "Type")?.Value,
Description = string.Join(",", x.Elements(ns + "Description").Select(elem=>elem.Value))
}).ToList()
}).FirstOrDefault();
}
}
}
If you dont wan't to care about finding the namespace, you might want to try the following:
var document = XDocument.Parse(xmlString);
var historyObject2 = document.Root.Descendants()
.Where(x=>x.Name.LocalName == "History")
.Select(historyElement => new History
{
Name = historyElement.Element(historyElement.Name.Namespace + "Name")?.Value,
Number = historyElement.Element(historyElement.Name.Namespace+ "Number")?.Value,
Items = historyElement.Elements(historyElement.Name.Namespace + "Item").Select(x => new Item()
{
//CreateDate = DateTime.Parse(x.Element("CreateDate")?.Value),
Type = x.Element(historyElement.Name.Namespace + "Type")?.Value,
Description = string.Join(",", x.Elements(historyElement.Name.Namespace + "Description").Select(elem => elem.Value))
}).ToList()
}).FirstOrDefault();

Formatting issue with a class generated xml in ASP.Net C#

My below my code which generate an xml and return the generated xml but the current format is not the structure expected:
My Class:
public class response
{
[StringLength(64)]
public string reference { get; set; }
public int responseCode { get; set; }
[StringLength(140)]
public string responseMessage { get; set; }
[StringLength(32)]
public string transactionId { get; set; }
public List<account> accounts { get; set; }
}
public class account
{
[StringLength(64)]
public string account_number { get; set; }
}
rs = "<?xml version='1.0' encoding='UTF-8'?><USSDResponse><Status>true</Status><StatusMessage>Account details returned for 08069262257</StatusMessage><SessionID>31853F5C-A1C1-2A6F-E054-8E1F65C33B15</SessionID><AccountNumber><AccountNo>0003893369</AccountNo><AccountStatus>ACCOUNT OPEN REGULAR</AccountStatus><AvailableBalance>17674.69</AvailableBalance><AccountName>IYEKE IKECHUKWU I.</AccountName><AccountCurrency>NGN</AccountCurrency><ProductName>CURRENT STAFF</ProductName></AccountNumber><AccountNumber><AccountNo>0064612613</AccountNo><AccountStatus>ACCOUNT OPEN REGULAR</AccountStatus><AvailableBalance>201132.18</AvailableBalance><AccountName>IKECHUKWU ISRAEL IYEKE</AccountName><AccountCurrency>NGN</AccountCurrency><ProductName>HIDA</ProductName></AccountNumber></USSDResponse>";
x.LoadXml(rs);
status = x.GetElementsByTagName("Status")[0].InnerText;
SessionID = x.GetElementsByTagName("SessionID")[0].InnerText;
if (status != null && status == "true")
{
var accts = x.GetElementsByTagName("AccountNo");
var names = x.GetElementsByTagName("ProductName");
if (accts.Count >= 2)
{
//var AcctNo = new accounts();
foreach (XmlElement a in accts)
{
var acctNo = a.InnerText.Substring(0, 10);
accounts.Add(new account { account_number = acctNo });
}
o.accounts = accounts;
o.reference = reference;
o.responseCode = 6;
o.responseMessage = "Please you can only purchase airtime in naira only and no kobo inclusive.";
o.transactionId = "Nil";
logger.Info($"Wrong amount: {amountString} including kobo entered by the user for mobile number: {msisdn}");
return o;
}
}
Result:
<response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<reference>565695769-8490890112091</reference>
<responseCode>6</responseCode>
<responseMessage>Please you can only purchase airtime in naira only and no kobo inclusive.</responseMessage>
<transactionId>Nil</transactionId>
<accounts>
<account><account_number>0003893369</account_number></account>
<account><account_number>0064612613</account_number></account>
</accounts>
</response>
My above code generate an xml and return the generated xml but the current format is not the structure expected:But I want the result to be exactly with the removal of tag <account_number></account_number>:
<response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<reference>565695769-8490890112091</reference>
<responseCode>6</responseCode>
<responseMessage>Please you can only purchase airtime in naira only and no kobo inclusive.</responseMessage>
<transactionId>Nil</transactionId>
<accounts>
<account>0003893369</account>
<account>0064612613</account>
</accounts>
</response>
Modify your class structure as below,
public class Accounts {
public Accounts ()
{
Account = new List<string>();
}
public List<string> Account { get; set; }
}
public class Response {
...
public Accounts Accounts { 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.

XMLSerialization for a List

I have class like this below shown. which contains the shopping items where the number can vary from 0 to n.
namespace SerializationPOC
{
public class ShoppingItems
{
public string CustomerName { get; set; }
public string Address { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public string Name { get; set; }
public string Price { get; set; }
}
}
Is it possible to get the class serialized like to get the XML Schema like below.
<?xml version="1.0" encoding="utf-8" ?>
<ShoppingItems>
<CustomerName>John</CustomerName>
<Address>Walstreet,Newyork</Address>
<Item1>Milk</Item1>
<Price1>1$</Price1>
<Item2>IceCream</Item2>
<Price2>1$</Price2>
<Item3>Bread</Item3>
<Price3>1$</Price3>
<Item4>Egg</Item4>
<Price4>1$</Price4>
<Item..n>Egg</Item..n>
<Price..n>1$</Price..n>
</ShoppingItems>
I would like to know if this can be achieved by using the Serilization if not whats the best way to achieve this Schema?
There is no standard serializer that supports that layout. You will have to do it yourself. Personally, I would say "you're doing it wrong"; I strongly suggest (if it is possible) using a format like
<Item name="IceCream" Price="1$"/>
or
<Item><Name>IceCream</Name><Price>1$</Price></Item>
both of which would be trivial with XmlSerializer.
LINQ-to-XML is probably your best option, something like:
var items = new ShoppingItems
{
Address = "Walstreet,Newyork",
CustomerName = "John",
Items = new List<Item>
{
new Item { Name = "Milk", Price = "1$"},
new Item { Name = "IceCream", Price = "1$"},
new Item { Name = "Bread", Price = "1$"},
new Item { Name = "Egg", Price = "1$"}
}
};
var xml = new XElement("ShoppingItems",
new XElement("CustomerName", items.CustomerName),
new XElement("Address", items.Address),
items.Items.Select((item,i)=>
new[] {
new XElement("Item" + (i + 1), item.Name),
new XElement("Price" + (i + 1), item.Price)}))
.ToString();
Can you please have a look on my article, [^]
As an example you can look into the below code. The Serialize method is given on the article.
var test = new ShoppingItems()
{
CustomerName = "test",
Address = "testAddress",
Items = new List<Item>()
{
new Item(){ Name = "item1", Price = "12"},
new Item(){Name = "item2",Price = "14"}
},
};
var xmlData = Serialize(test);
And it will return the string given below,
<?xml version="1.0" encoding="utf-16"?>
<ShoppingItems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CustomerName>test</CustomerName>
<Address>testAddress</Address>
<Items>
<Item>
<Name>item1</Name>
<Price>12</Price>
</Item>
<Item>
<Name>item2</Name>
<Price>14</Price>
</Item>
</Items>
</ShoppingItems>

Categories

Resources