Finding and Filtering XML Data - c#

I have an XML document here:
<?xml version="1.0" encoding="utf-8" ?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<CD>
<TITLE>Test Title 1</TITLE>
<ARTIST>Test Name 1</ARTIST>
<COUNTRY>Test Country 1</COUNTRY>
<COMPANY>Test Company 1</COMPANY>
<PRICE>100.00</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Test Title 3</TITLE>
<ARTIST>Test Name 3</ARTIST>
<COUNTRY>Test Country 3</COUNTRY>
<COMPANY>Test Company 3</COMPANY>
<PRICE>1.99</PRICE>
<YEAR>1984</YEAR>
</CD>
<CD>
<TITLE>Test Title 2</TITLE>
<ARTIST>Test Name 2</ARTIST>
<COUNTRY>Test Country 2</COUNTRY>
<COMPANY>Test Company 2</COMPANY>
<PRICE>19.99</PRICE>
<YEAR>1985</YEAR>
</CD>
</CATALOG>
What I am trying to do is find all the CDs that have a year of 1985. I'm very new to LINQ to XML and I have no idea what I'm doing. Because most internet resources are very specific example, I'm having trouble applying it to my example.
Here's the C# that I've coded so far:
namespace ReadingXML
{
class Program
{
static void Main(string[] args)
{
XElement xelement = XElement.Load("..\\..\\music.xml");
IEnumerable<XElement> music = xelement.Elements();
/*// Read the entire XML
foreach (var item in catalogues)
{
Console.WriteLine(item);
}
Console.ReadLine();*/
var query = from item in music.Descendants("CD")
select new { year = item.Element("YEAR").Equals(1985) };
foreach (var item in query)
Console.WriteLine(item.ToString());
Console.ReadLine();
}
}
}
Can someone please tell me how I can achieve what I'm trying to do and/or why my code isn't functioning?

XDocument X = XDocument.Load(#"XMLFileLocation");
var CDsIn1985 = X.Element("CATALOG").Elements("CD").Where(E => E.Element("YEAR").Value == "1985");
foreach (var item in CDsIn1985)
{
Console.WriteLine(String.Format("Title : {0}, Artist : {1}", item.Element("TITLE").Value, item.Element("ARTIST").Value));
}

Another away is to use String Interpolation
foreach (var item in CDsIn1985)
{
Console.WriteLine(String.Format($"Title : {item.Element("TITLE").Value}, Artist : { item.Element("ARTIST").Value}"));
}

Related

How to get value of same nodes in XML in c#

I want to get the value of artist (Bob Dylan) for title "Greatest Hits" in the xml below
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<price>10.0</price>
</cd>
<cd>
<title>Greatest Hits</title>
<artist>Bob Dylan</artist>
<price>10.90</price>
</cd>
</catalog>
Adapt it as you need ...
using System.Xml;
static void GetArtistFromXml()
{
var xml = "<?xml version=\"1.0\" encoding=\"ISO - 8859 - 1\"?><catalog><cd><title>Empire Burlesque</title><artist>Bob Dylan</artist><price>10.90</price></cd><cd><title>Hide your heart</title><artist>Bonnie Tyler</artist><price>10.0</price></cd><cd><title>Greatest Hits</title><artist>Bob Dylan</artist><price>10.90</price></cd></catalog>";
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
var artistElement = xmlDocument.DocumentElement.SelectSingleNode("//cd[title[text()=\"Greatest Hits\"]]/artist");
Console.WriteLine(artistElement.InnerText);
}
It is better to use LINQ to XML API. It is available in the .Net Framework since 2007.
c#
void Main()
{
const string filename = #"e:\Temp\AmeyP.xml";
XDocument xdoc = XDocument.Load(filename);
string artist = xdoc.Descendants("cd")
.Where(x => x.Element("title").Value.Equals("Greatest Hits"))
.Elements("artist").FirstOrDefault()?.Value;
Console.WriteLine(artist);
}
Output
Bob Dylan

C# : XML Parsing : Group XML on a node and then subGroup underneath the same group

<?xml version="1.0" encoding="UTF-8"?>
<Batch Id="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PurchaseOrders>
<PurchaseOrder id="xx267681">
<Header>
<AccountNumber>999</AccountNumber>
<ShipDate>2/10/2009</ShipDate>
</Header>
<PurchaseOrderDetails>
<Item>
<ItemNumber>yy235240</ItemNumber>
<Quantity>200</Quantity>
</Item>
<Item>
<ItemNumber>yy336820</ItemNumber>
<Quantity>3</Quantity>
</Item>
</PurchaseOrderDetails>
</PurchaseOrder>
<PurchaseOrder id="zz267456">
<Header>
<AccountNumber>123</AccountNumber>
<ShipDate>2/10/2009</ShipDate>
</Header>
<PurchaseOrderDetails>
<Item>
<ItemNumber>nn235240</ItemNumber>
<Quantity>200</Quantity>
</Item>
</PurchaseOrderDetails>
</PurchaseOrder>
</PurchaseOrders>
</Batch>
Attached above is the XML file I am trying to parse. My current C# code find all items in the XML file and assigns it against the PO#. But the recent XML file I got to know that there can be multiple PO# in the same XML file and hence I now need to find only those items matching to that PO#.
So in above example, PONumber with xx267681 has 2 items whereas 2nd PO has only item.
Here is what I tried so far.
try
{
ArrayList ItemsInFeed = new ArrayList();
XDocument xDoc = XDocument.Load(fileName);
foreach (var node in xDoc.Descendants("PurchaseOrder"))
{
poID = node.Attribute("id").Value;
}
foreach (var node in xDoc.Descendants("Item"))
{
Items itemRcd = new Items();
itemRcd.ItemNr = node.Descendants("ItemNumber")?.First().Value;
ItemsInFeed.Add(itemRcd);
}
if (ItemsInFeed.Count > 0)
{
// Do other logic based on the items linked to each PO#.
// Issue found : So far each XML file has one PO#, but latest XML file received has more than PO# and underlying items.
ItemsInFeed.Clear();
}
}
catch (Exception ex)
{
//Catch exception here
}
Try following :
XDocument xDoc = XDocument.Load(fileName);
var results = xDoc.Descendants("PurchaseOrder").Select(x => new
{
poID = (string)x.Attribute("id"),
items = x.Descendants("Item").Select(y => new
{
itemNumber = (string)y.Element("ItemNumber"),
quantity = (int)y.Element("Quantity")
}).ToList()
}).ToList();

c# Merging two XMLs giving error

I am trying to merge two XMLs with same structure but different data into one.
I am getting this error: A node of type Document cannot be added to content.
Below is my code
var productElements =
testGroupProvider.GetTestGroup().ProductTests.Select(
productTest => new XElement(xNamespace + "Product",
new XElement(xNamespace + "ExternalId", productTest.ProductNameKey),
new XElement(xNamespace + "Name", testGroupProvider.GetProductName(productTest)),
new XElement(xNamespace + "ImageUrl", ChoiceBaseHostName + GetProductImageUrl(productTest, TargetDatabase))));
var root = new XDocument(
new XElement(xNamespace + "Feed",
new XAttribute("xmlns", xNamespace),
new XAttribute("name", BVFeedsName),
new XAttribute("incremental", "true"),
new XAttribute("extractDate", DateTime.Now.ToString("o")),
new XElement(xNamespace + "Categories",
new XElement(xNamespace + "Category",
new XElement(xNamespace + "ExternalId", testGroupProvider.GetProductGroup().Id),
new XElement(xNamespace + "Name", testGroupProvider.GetProductGroup().Name),
testGroupProvider.GetTestGroup().Name),
new XElement(xNamespace + "Products", productElements)));
var filePath = #"D:\testXML\test.xml";
XElement xml = XElement.Load(filePath);
xml.Add(root);
xml.Save(filePath);
Can anyone tell me what i am doing wrong.
This is the XML structure in test.xml
<?xml version="1.0" encoding="utf-8"?>
<Feed xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6" name="Choice" incremental="true" extractDate="2016-07-12T15:24:44.5732750+10:00">
<Categories>
<Category>
<ExternalId>{09B3B4FB-F5CF-4522-BE96-4C4B535580C3}</ExternalId>
<Name>Cereal and muesli</Name>
</Category>
</Categories>
<Products>
<Product>
<ExternalId>coles-almond-hazelnut-macadamia-cluster-fusions</ExternalId>
<Name>Coles Almond, Hazelnut & Macadamia Cluster Fusions</Name>
<ImageUrl></ImageUrl>
</Product>
</Products>
</Feed>
The second XML has the same structure with different products
<?xml version="1.0" encoding="utf-8"?>
<Feed xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6" name="Choice" incremental="true" extractDate="2016-07-12T15:24:44.5732750+10:00">
<Categories>
<Category>
<ExternalId>{12}</ExternalId>
<Name>cat1</Name>
</Category>
</Categories>
<Products>
<Product>
<ExternalId>Id</ExternalId>
<Name>Ccoles</Name>
<ImageUrl></ImageUrl>
</Product>
</Products>
</Feed>
I want to combine them like below
<?xml version="1.0" encoding="utf-8"?>
<Feed xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6" name="Choice" incremental="true" extractDate="2016-07-12T15:24:44.5732750+10:00">
<Categories>
<Category>
<ExternalId>{09B3B4FB-F5CF-4522-BE96-4C4B535580C3}</ExternalId>
<Name>Cereal and muesli</Name>
</Category>
<Category>
<ExternalId>{12}</ExternalId>
<Name>cat1</Name>
</Category>
</Categories>
<Products>
<Product>
<ExternalId>coles-almond-hazelnut-macadamia-cluster-fusions</ExternalId>
<Name>Coles Almond, Hazelnut & Macadamia Cluster Fusions</Name>
<ImageUrl></ImageUrl>
</Product>
<Product>
<ExternalId>Id</ExternalId>
<Name>Ccoles</Name>
<ImageUrl></ImageUrl>
</Product>
</Products>
</Feed>
A xml document must have only one root.
Working with the documents you attached, you can replace the xml.Add(root); with the following (i.e. it will add each node under one root to the other xml root)
foreach (var child in root.Root.Elements())
{
xml.Element(child.Name.ToString()).Add(child.Nodes());
}
Edit - A further generalization
You can generalize the above code using a Merge extension of 2 XElements so that it reads as follows
foreach (var child in root.Elements())
{
xml.Element(child.Name.ToString()).Merge(child, xNamespace + "ExternalId");
}
Having defined the extension
public static void Merge(this XElement root1, XElement root2, XName element_id)
{
root1.Add(root2.Elements().Except(root1.Elements(), new MyComparer(element_id)));
}
with a xml comparer
public class MyComparer : IEqualityComparer<XElement>
{
private XName _element_id;
public MyComparer(XName element_id)
{
_element_id = element_id;
}
public bool Equals(XElement x, XElement y)
{
return x.Element(_element_id).Value.Equals(y.Element(_element_id).Value);
}
public int GetHashCode(XElement el)
{
return el.Element(_element_id).Value.GetHashCode();
}
}
Select correct nodes to add and correct nodes to be added.
var filePath = #"D:\testXML\test.xml";
XElement xml = XElement.Load(filePath);
var xmlCategories = xml.Descendants("Categories").First();
var rootCategories = root.Descendants("Category");
xmlCategories.Add(rootCategories);
var xmlProducts = xml.Descendants("Products").First();
var rootProducts = root.Descendants("Product");
xmlProducts.Add(rootProducts);
xml.Save(filePath);
Be crystal clear what you are doing.
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication2
{
class Program
{
const string FILENAME1 = #"c:\temp\test1.xml";
const string FILENAME2 = #"c:\temp\test2.xml";
static void Main(string[] args)
{
XDocument doc1 = XDocument.Load(FILENAME1);
XDocument doc2 = XDocument.Load(FILENAME2);
XElement category1 = doc1.Descendants().Where(x => x.Name.LocalName == "Categories").FirstOrDefault();
XElement category2 = doc2.Descendants().Where(x => x.Name.LocalName == "Categories").FirstOrDefault();
category1.Add(category2.Descendants());
XElement product1 = doc1.Descendants().Where(x => x.Name.LocalName == "Products").FirstOrDefault();
XElement product2 = doc2.Descendants().Where(x => x.Name.LocalName == "Products").FirstOrDefault();
product1.Add(product2.Descendants());
}
}
}
Try this, sorry about the VB
'second is The second XML has the same structure with different products
Dim combined As XElement = New XElement(test) 'create copy of test.xml
combined.<Categories>.LastOrDefault.Add(second.<Categories>.Elements)
combined.<Products>.LastOrDefault.Add(second.<Products>.Elements)
or
'if test can be used to combine then
test.<Categories>.LastOrDefault.Add(second.<Categories>.Elements)
test.<Products>.LastOrDefault.Add(second.<Products>.Elements)
The result is
<Feed name="Choice" incremental="true" extractDate="2016-07-12T15:24:44.5732750+10:00" xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6">
<Categories>
<Category>
<ExternalId>{09B3B4FB-F5CF-4522-BE96-4C4B535580C3}</ExternalId>
<Name>Cereal and muesli</Name>
</Category>
<Category>
<ExternalId>{12}</ExternalId>
<Name>cat1</Name>
</Category>
</Categories>
<Products>
<Product>
<ExternalId>coles-almond-hazelnut-macadamia-cluster-fusions</ExternalId>
<Name>Coles Almond, Hazelnut & Macadamia Cluster Fusions</Name>
<ImageUrl></ImageUrl>
</Product>
<Product>
<ExternalId>Id</ExternalId>
<Name>Ccoles</Name>
<ImageUrl></ImageUrl>
</Product>
</Products>
</Feed>
The test data I used is
Dim test As XElement =
<Feed xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6" name="Choice" incremental="true" extractDate="2016-07-12T15:24:44.5732750+10:00">
<Categories>
<Category>
<ExternalId>{09B3B4FB-F5CF-4522-BE96-4C4B535580C3}</ExternalId>
<Name>Cereal and muesli</Name>
</Category>
</Categories>
<Products>
<Product>
<ExternalId>coles-almond-hazelnut-macadamia-cluster-fusions</ExternalId>
<Name>Coles Almond, Hazelnut & Macadamia Cluster Fusions</Name>
<ImageUrl></ImageUrl>
</Product>
</Products>
</Feed>
Dim second As XElement =
<Feed xmlns="http://www.bazaarvoice.com/xs/PRR/ProductFeed/5.6" name="Choice" incremental="true" extractDate="2016-07-12T15:24:44.5732750+10:00">
<Categories>
<Category>
<ExternalId>{12}</ExternalId>
<Name>cat1</Name>
</Category>
</Categories>
<Products>
<Product>
<ExternalId>Id</ExternalId>
<Name>Ccoles</Name>
<ImageUrl></ImageUrl>
</Product>
</Products>
</Feed>
The XElements can be loaded like this
test = XElement.Load("PATH")
second = XElement.Load("second PATH")
and saved like this
test.Save("PATH")
second.Save("second PATH")
combined.Save("combined PATH")

Descendants not found even if they exist in XDocument in C#

I am having problems with getting descendant with specific name. I have hugh XML that basically is made of lots of this elements:
<?xml version="1.0" encoding="utf-8"?>
<Search_Results xmlns="https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.5/OutputFile.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.5/OutputFile.xsd https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.5/OutputFile.xsd">
<Entity Record="28" ResultID="12460985">
<GeneralInfo>
<EntityType>Individual</EntityType>
<Name>Jón Jónsson</Name>
<DOB>01/01/0001</DOB>
<DOBParsed />
<AccountID>ABS-ASSOC-10-109</AccountID>
<IDLabel>Account ID</IDLabel>
<IDNumber>ABS-ASSOC-10-109</IDNumber>
<AddressType>Current</AddressType>
<PostalCode>Somalia</PostalCode>
</GeneralInfo>
<RecordDetailInfo>
<EntityType>Individual</EntityType>
<SearchDate>2016-05-13 09:53:50Z</SearchDate>
<Origin>Automatic Batch</Origin>
<FirstName>Jón</FirstName>
<LastName>Jónsson</LastName>
<FullName>Jón Jónsson</FullName>
<AdditionalInfo>
<Type>Date of Birth</Type>
<Information>01/01/0001</Information>
</AdditionalInfo>
<Addresses>
<Type>Current</Type>
<PostalCode>Somalia</PostalCode>
</Addresses>
<Identifications>
<Type>Account ID</Type>
<Number>ABS10-109</Number>
</Identifications>
</RecordDetailInfo>
<WatchList>
<Match ID="1">
<EntityName>Jonsson</EntityName>
<EntityScore>96</EntityScore>
<BestName>Jonsson, Jon Orn</BestName>
<BestNameScore>96</BestNameScore>
<FileName>WorldCompliance - Full.BDF</FileName>
<SourceDate>2016-05-11 05:01:00Z</SourceDate>
<DistributionDate>2016-05-12 14:59:39Z</DistributionDate>
<ResultDate>2016-05-13 09:53:50Z</ResultDate>
<EntityUniqueID>WX0003219444</EntityUniqueID>
<MatchDetails>
<Entity Type="2">
<Number>3219444</Number>
<Date>9/3/2012</Date>
<Reason>International</Reason>
<CheckSum>69185</CheckSum>
<Gender>Male</Gender>
<Name>
<First>Jon Orn</First>
<Last>Jonsson</Last>
<Full>Jon Orn Jonsson</Full>
</Name>
<Notes>Source.</Notes>
<Addresses>
<Address ID="1" Type="4">
<Country>Iceland</Country>
</Address>
</Addresses>
<IDs>
<ID ID="1" Type="27">
<Number>3219444</Number>
</ID>
</IDs>
<Descriptions>
<Description ID="1" Type="10">
<Value>Honorary Consul of Iceland in Saskatchewan, Canada</Value>
<Notes>Starting 2002 Ending 2014</Notes>
</Description>
<Description ID="2" Type="22">
<Value>Link to WorldCompliance Online Database</Value>
<Notes>Jonsson, Jon Orn | https://members.worldcompliance.com/metawatch2.aspx?id=e0399c29-7c5e-4674-874c-f36fdb19052e</Notes>
</Description>
<Description ID="3" Type="22">
<Value>Sources of Record Information</Value>
<Notes>http://brunnur.mfa.is/interpro/utanr/HBvefur.nsf/Pages/IslSendiradIsl?OpenDocument&amp | CountryNr=1(Canada)&amp | Lang=44') | http://www.international.gc.ca/protocol-protocole/assets/pdfs/Diplomatic_List.pdf | http://www.inlofna.org/Elfros/newsletter%20January%202010.pdf | http://publications.gc.ca/collections/Collection/E12-3-2002E.pdf | http://www.onlygolfnews.com/golf-canada-saskatchewan/saskatchewan-golf-first-fort-lacrosse-ted-brandon-over-new-last-snow.htm | http://www.ops.gov.sk.ca/Consular-Officers</Notes>
</Description>
</Descriptions>
</Entity>
</MatchDetails>
</Match>
</WatchList>
</Entity>
</Search_Results>
I am trying to reach all elements with name: Entity and later I want to go through all of them and get values from their descendants with name "Reason".
But non of the Entity elements is found with this line:
var entityList = xmlDoc.Descendants(nameSpace + "Entity").ToList();
This is a whole method I am using:
public static void GetIBANAndBicValuesFromXML(XDocument xmlDoc)
{
var reasons = new List<string>();
XNamespace nameSpace =
"https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.5/";
var entityList = xmlDoc.Descendants(nameSpace + "Entity").ToList();
if (entityList != null)
{
foreach (var reason in entityList.Select(entity => entity.Elements(nameSpace + "Reason"))
.Where(reasonsList => reasonsList != null).SelectMany(reasonsList => reasonsList))
{
string reasonValue = reason.Value;
reasons.Add(reasonValue);
}
}
}
And this is a call to this method:
private static void Main(string[] args)
{
var xmlFile = "C:\\temp\\indi2.xml";
var x = XDocument.Load("C:\\temp\\Individuals.xml");
XMLParse.GetIBANAndBicValuesFromXML(x);
}
I have tried namespace like this as well:
"https://support.bridgerinsight.lexisnexis.com/downloads/xsd/4.5/OutputFile.xsd"
But no success.
Anybody sees what I am doing wrongly?
You can use Linq to filter with LocalName:
string fileName = "1.txt";
var xDoc = XDocument.Load(fileName);
var neededElements = xDoc.Descendants().Where(x => x.Name.LocalName == "Entity");
Console.WriteLine("Found {0} Entitys", neededElements.Count());
foreach(var el in neededElements)
{
Console.WriteLine(el);
}

how can I turn a set of csv lines into xml?

Is there a way to take a spreadsheet and turn it into xml file below?
<?xml version="1.0"?>
<ArrayOfBusiness xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Business>
<Name>Company Name 1</Name>
<AddressList>
<Address>
<AddressLine>123 Main St.</AddressLine>
</Address>
</AddressList>
</Business>
<Business>
<Name>Company Name 2</Name>
<AddressList>
<Address>
<AddressLine>1 Elm St.</AddressLine>
</Address>
<Address>
<AddressLine>2 Elm St.</AddressLine>
</Address>
</AddressList>
</Business>
</ArrayOfBusiness>
I put this in LinqPad and it did what you needed. If you've never used LinqPad... well now's a great time to start.
var csvs = new List<string>();
csvs.Add( "Company Name 1,123 Main St.");
csvs.Add("Company Name 2,1 Elm St.,2 Elm St.");
var xml =
(from c in csvs
let split = c.Split(',')
select // split
new XElement("ArrayOfBusiness",
new XElement("Business",
new XElement("Name", split[0] ),
new XElement("AddressList",
new XElement("Address"
,
(from s in split.Skip(1) // skip the first split
select
new XElement("AddressLine", s))
)
)))); // <-- is it LISP?
xml.Dump();
Results:
<ArrayOfBusiness>
<Business>
<Name>Company Name 1</Name>
<AddressList>
<Address>
<AddressLine>123 Main St.</AddressLine>
</Address>
</AddressList>
</Business>
<Business>
<Name>Company Name 2</Name>
<AddressList>
<Address>
<AddressLine>1 Elm St.</AddressLine>
<AddressLine>2 Elm St.</AddressLine>
</Address>
</AddressList>
</Business>
</ArrayOfBusiness>
It isn't exactly what you wanted, but looks functionally equivalent to me. Might need a bit of tweaking in the LINQ.
Write to file with: File.WriteAllText(#"c:\temp\addresses.xml", xml.ToString());
Parsing the .csv file into 'Business' objects should be straightforward.
Its then a simple case of using the XmlSerializer class to generate the xml.
I would say yes, but with out seeing the CSV file it is hard to say.
If your CSV was somthing like this:
Name, Address1, Address2
Company Name 1,123 Main St.,
Company Name 2,1 Elm St.,1 Elm St.
you could easily parse this into a class.
class Business
{
public string Name { get; set; }
public List<Address> AddressList { get; set; }
}
class Address
{
public string AddressLine { get; set; }
}
(untested)

Categories