Parse XML and populate in List Box - c#

I'm a newbie to C#.
I want to develop C# List box in Windows Form. I found this link to be helpful.
But the input to the List box will be an XML of the following format:
<LISTBOX_ST>
<item><CHK></CHK><SEL>00001</SEL><VALUE>val01</VALUE></item>
<item><CHK></CHK><SEL>00002</SEL><VALUE>val02</VALUE></item>
<item><CHK></CHK><SEL>00003</SEL><VALUE>val03</VALUE></item>
<item><CHK></CHK><SEL>00004</SEL><VALUE>val04</VALUE></item>
<item><CHK></CHK><SEL>00005</SEL><VALUE>val05</VALUE></item>
</LISTBOX_ST>
The XML has to be parsed and should be populated in the list box. When particular item in the list is selected, it's CODE should be returned(i.e the value of SEL node).
Any pointers/suggestions as how to parse effectively and display in List.
The XML is coming from SAP and expecting to have around 300 to 400 records.

You could use Linq to XML to do it like this.
XDocument xmldoc = XDocument.Load(xmlStream);
var items = (from i in xmldoc.Descendants("item")
select new { Item = i.Element("SEL").Value, Value = i.Element("VALUE").Value }).ToList();
listBox1.DataSource = items;
listBox1.DisplayMember = "Item";
listBox1.ValueMember = "Value";

Using Linq-to-XML, you can do this:
public partial class item
{
public object CHK { get; set; }
public int SEL { get; set; }
public string VALUE { get; set; }
}
and somewhere in your code:
XDocument lbSrc = XDocument.Load("yourfile.xml");
List<item> _lbList = new List<item>();
foreach (XElement item in lbSrc.Descendants("item"))
{
_lbList.Add(new item { CHK= item.Element("CHK").Value,
SEL = Convert.ToInt32(item.Element("SEL").Value),
VALUE = item.Element("VALUE").Value });
}
and then assign that to your listbox:
lbYourListbox.DataSource = _lbList;
lbYourListbox.DisplayMember = "VALUE";
lbYourListbox.ValueMember = "SEL";
That should do it!

Related

unable select combobox value after form is loaded

cant select combo item by value after its passed to form. Comb is populated properly i get all the customers displayed by Text.
public OrderViewerForm(string orderId)
{
InitializeComponent();
PopulateCustomerCombobox();
PopulateForm(orderId);
PopulateProductsTable();
}
private void PopulateForm(string orderId)
{
OrderModel order = db.LoadOrder(orderId);
List<ProductsOrderedModel> productsOrdered = db.ProductsOrdered_Load(orderIdValue.Text);
orderIdValue.Text = order.Id.ToString();
customerIdValue.Text = order.CustomerId.ToString();
customerIdCombo.SelectedValue = order.CustomerId;
}
private void PopulateCustomerCombobox()
{
customerIdCombo.Items.Clear();
List<CustomerModel> customer = db.CustomerGet_All();
foreach (CustomerModel c in customer)
{
customerIdCombo.DisplayMember = "Text";
customerIdCombo.ValueMember = "Value";
customerIdCombo.Items.Add(new { Text = c.FullInfo, Value = c.Id });
}
}
At the end order.CustomerId is set properly but customerIdCombo.SelectedValue stays null. What am I doing wrong?
I would suggest switching to databinding here. Your foreach looks weird by the way.
private void PopulateCustomerCombobox()
{
customerIdCombo.DisplayMember = "Text";
customerIdCombo.ValueMember = "Value";
customerIdCombo.DataSource = db.CustomerGet_All().Select(c=> new { Text = c.FullInfo, Value = c.Id});
}
Thinking about it you may want to drop the hole anonymous type thing. why not simply bind the list you get from CustomerGet_All?

Load repeated elements from an XML file

I am looking to load repeated elements from an XML file I have called initialInspections.xml. The problem is that the system needs to be dynamic and to allow as many different inspectionNotes to be added. I need to input all of them even though they have the same name.
If someone could please give me a method of doing this I would be extremely appreciative, since I have been searching for almost 3 hours now and I haven't found anything that works.
I need all off the data from within each inspectionNote node, and it will be put into an array of a structure called initialInspectionNotes.
Here is what I have up to now:
public int propertyID;
public string initialInspectorUsername;
public DateTime intialDateTime;
public struct initialInspectionNotes
{
public string locationWithinProperty;
public string locationExtraNote;
public string costCode;
public float estimatedTime;
}
private void finalInspection_Load(object sender, EventArgs e)
{
//Open the intialInspections xml file and load the values into the form
XmlDocument xdoc = new XmlDocument();
FileStream rFile = new FileStream(values.xmlInitialFileLocation, FileMode.Open);
xdoc.Load(rFile);
XmlNodeList list = xdoc.GetElementsByTagName("initialInspection");
for (int i = 0; i < list.Count; i++)
{
XmlElement initialInspection = (XmlElement)xdoc.GetElementsByTagName("initialInspection")[i];
XmlElement initialInspector = (XmlElement)xdoc.GetElementsByTagName("userInspection")[i];
XmlElement dateTime = (XmlElement)xdoc.GetElementsByTagName("dateTime")[i];
propertyID = int.Parse(initialInspection.GetAttribute("propertyID"));
initialInspectorUsername = initialInspector.InnerText;
intialDateTime = DateTime.Parse(dateTime.InnerText);
}
rFile.Close();
}
The XML looks like this:
<?xml version="1.0" standalone="yes"?>
<initialInspections>
<initialInspection propertyID="1">
<userInspection>defaultadmin</userInspection>
<dateTime>07/11/2015 17:15:20</dateTime>
<inspectionNote>
<location>Dining Room</location>
<locationNote>Remove whole carpet, leave underlay</locationNote>
<CostCode>L1</CostCode>
<estimatedTime>5</estimatedTime>
</inspectionNote>
<inspectionNote>
<location>Other - See Notes</location>
<locationNote>On the marked area with orange spray paint.</locationNote>
<CostCode>B1</CostCode>
<estimatedTime>12</estimatedTime>
</inspectionNote>
</initialInspection>
</initialInspections>
Any help would be much appreciated.
class Note
{
public string Location { get; set; }
public string LocationNote { get; set; }
public string CodeCost { get; set; }
public string EstimatedTime { get; set; }
}
var xml = XElement.Load(...your xml path here );
var data = xml.Descendants("initialInspection").Elements("inspectionNote").Select(n => new Note()
{
Location = n.Element("location").Value,
LocationNote = n.Element("locationNote").Value,
CodeCost = n.Element("CostCode").Value,
EstimatedTime = n.Element("estimatedTime").Value
}).ToList();
One possibility would be to use the LINQ2XML and the LINQ Descendants method to fetch all inspectionNotes at once:
var xml = XDocument.Load(fileLocation); // for example c:\temp\input.xml
// fetch all inspectionNotes
var inspectionNotes = xml.Root.Descendants("inspectionNote").ToList();
// TODO: error handling!
// map inspectionNote node to custom structure
var arrayOfNotes = inspectionNotes.Select (n => new initialInspectionNotes
{
costCode = n.Element("CostCode").Value,
estimatedTime = float.Parse(n.Element("estimatedTime").Value),
locationExtraNote = n.Element("locationNote").Value,
locationWithinProperty = n.Element("location").Value,
})
// and convert the result to array holding elements of the custom structure
.ToArray();
foreach (var note in arrayOfNotes)
{
Console.WriteLine(note.locationExtraNote);
}
The output is:
Remove whole carpet, leave underlay
On the marked area with orange spray paint.
Same logic applies if you want to read and map another XML nodes (f.e. initialInspection).
If you need to use XmlReader then use XPath in order to fetch the inner inspectionNote elements and the values of every inspectionNote element, using XmlNode.SelectSingleNode and XmlNode.SelectNodes:
//Open the intialInspections xml file and load the values into the form
XmlDocument xdoc = new XmlDocument();
FileStream rFile = new FileStream(values.xmlInitialFileLocation, FileMode.Open);
xdoc.Load(rFile);
XmlNodeList list = xdoc.GetElementsByTagName("initialInspection");
// create list of initialInspectionNotes in order to add as many nodes as needed
var notes = new List<initialInspectionNotes>();
// map data
for (int i = 0; i < list.Count; i++)
{
// read data
XmlElement initialInspection = (XmlElement)xdoc.GetElementsByTagName("initialInspection")[i];
XmlElement initialInspector = (XmlElement)xdoc.GetElementsByTagName("userInspection")[i];
XmlElement dateTime = (XmlElement)xdoc.GetElementsByTagName("dateTime")[i];
propertyID = int.Parse(initialInspection.GetAttribute("propertyID"));
initialInspectorUsername = initialInspector.InnerText;
intialDateTime = DateTime.Parse(dateTime.InnerText);
// fetch notes!
var inspectionNotes = initialInspection.SelectNodes("inspectionNote");
foreach (XmlNode inspectionNote in inspectionNotes)
{
// insert data into list
notes.Add(new initialInspectionNotes
{
locationExtraNote = inspectionNote.SelectSingleNode("locationNote").InnerText,
costCode = inspectionNote.SelectSingleNode("CostCode").InnerText,
locationWithinProperty = inspectionNote.SelectSingleNode("location").InnerText
});
}
}
// convert to array if needed
//var arrayOfNotes = notes.ToArray();
rFile.Close();
Regardless of how many inspectionNote elements the XML contains, the list resp. array will read them all.
class InitialInspectionNotes
{
public string Location { get; set; }
public string LocationNote { get; set; }
public string CodeCost { get; set; }
public string EstimatedTime { get; set; }
}
var xdoc = XDocument.Load("yourpath\filename.xml");
var dataXml = xdoc.Descendants("initialInspection").Elements("inspectionNote").Select(n => new InitialInspectionNotes()
{
Location = n.Element("location").Value,
LocationNote = n.Element("locationNote").Value,
CodeCost = n.Element("CostCode").Value,
EstimatedTime = n.Element("estimatedTime").Value
}).ToList();
var xmlList = new List<object>();
for (int i = 0; i < dataXml.Count; i++)
{
xmlList.Add(dataXml[i]);
}
Despite all the answers above might have worked, I have however found it quite complicated for reading just elements. I found a simpler solution which I would like to share for future audience in this case.
Supposing you have read the document stream into XmlDocument object named as document.
var dataNodes = document.GetElementsByTagName("Data");
var toList = dataNodes.OfType<XmlElement>().ToList();
In my case, Data node was not being called repeatedly. Hence this works, now I was able to append multiple nodes with the same name.

How to generate a treeview with group format? ( Letter that indicate the starting word )

I am developing an ASP.NET website and have a treeview to display countries which store in a MYSQL DB.
I am using this code to bind the data to treeview.
dt_Record is a datatable.
private void get_Countries()
{
try
{
dt_Record.Clear();
dt_Record = objCommonMethods_Bll.Get_Countries();
if (dt_Record.Rows.Count != 0)
{
foreach (DataRow dr in dt_Record.Rows)
{
TreeNode node = new TreeNode();
node.Text = dr["name"].ToString();
node.Value = dr["Countries_id"].ToString();
tvCountries.Nodes.Add(node);
}
}
}
catch (Exception)
{
throw;
}
}
So it displaying the countries like this
But I want to display countries like this. With a group letter to easily recognise the starting letter which can not be click.
Can I achieve above format? Then how to do that?
Thank you very much.
I have done this using LINQ query but in my case I have user a datastructure for a model instead of from database.
But you can use database in your scenario.
Here is my code:
1) I have created a class to use it as table.
public class Country
{
public string Name { get; set; }
}
2) I have made a List with data filled, & in your case you are getting data from your database.
List<Country> countriesList = new List<Country>()
{
new Country{Name="Algeria"},
new Country{Name="Angola"},
new Country{Name="Benin"},
new Country{Name="Botswana"},
new Country{Name="Burkina Faso"},
new Country{Name="Burundi"},
new Country{Name="Cameroon"},
new Country{Name="Cape Verde"},
};
3) and finally written the LINQ query to get the Grouped data as::
var temp = (from con in countriesList
group con by con.Name[0] into gr
select new
{
Key = gr.Key,
Value = gr.ToList()
}).ToList();

Saving values into List in a class by using LINQ

I have a class Item with a string List ImagesUrl property:
public class Item
{
string Name { get; set; }
List<string> ImagesUrl { get; set; }
..
}
And I want to parse a XML file and save each node item into var items. In node item there are nodes img1, .. , img5 and right these I want to save into the Img property by using LINQ command like this:
var items = from item in xmlDocument.Descendants("item")
select new Item
{
Name = item.Element("name").Value,
ImagesUrl = item.Element("img1").Value, //....?
..
};
How you can see, I don't know how I could save the img1..5 values in LINQ. Could someone help me?
var items = from item in xmlDocument.Descendants("item")
select new Item
{
Name = item.Element("name").Value,
ImagesUrl = Enumerable.Range(1,5).Select(x => item.Element("img"+x).Value).ToList();
};
Code is self-explanatory here.
Universal solution independent on count of imgX elements
var items = from item in Xml.Descendants("item")
select new Item
{
Name = item.Element("name").Value,
ImagesUrl = item.Elements()
.Where(e => e.Name.LocalName.StartsWith("img"))
.Select(e => e.Value)
.ToList()
};

limit number of listbox items to be displayed on load, programmatically

I have a Silverlight 2.0 listbox which reads in data from a custom list # SharePoint 2007. How may i limit the number of items to be displayed on load of Page.xaml?
Here i have # Page.xaml.cs:
private void ProcessResponse()
{
XDocument results = XDocument.Parse(_responseString);
_StaffNews = (from item in results.Descendants(XName.Get("row", "#RowsetSchema"))
//where !item.Element("NewsThumbnail").Attribute("src").Value.EndsWith(".gif")
select new StaffNews()
{
Title = item.Attribute("ows_Title").Value,
NewsBody = item.Attribute("ows_NewsBody").Value,
NewsThumbnail = FormatImageUrl(item.Attribute("ows_NewsThumbnail").Value),
DatePublished = item.Attribute("ows_Date_Published").Value,
PublishedBy = item.Attribute("ows_PublishedBy").Value,
}).ToList();
this.DataContext = _StaffNews;
//NewsList.SelectedIndex = -1;
}
You can put .Take(20) behind ToList() to take only 20 items from the list.
Take method allows you to set a limit on the items. It will only iterate the collection until the max count is reached. You can just use it instead of ToList() or in case of _StaffNews is defined as List<T>, just combine them .Take(items).ToList();
private void ProcessResponse()
{
var items = 10;
XDocument results = XDocument.Parse(_responseString);
_StaffNews = (from item in results.Descendants(XName.Get("row", "#RowsetSchema"))
//where !item.Element("NewsThumbnail").Attribute("src").Value.EndsWith(".gif")
select new StaffNews()
{
Title = item.Attribute("ows_Title").Value,
NewsBody = item.Attribute("ows_NewsBody").Value,
NewsThumbnail = FormatImageUrl(item.Attribute("ows_NewsThumbnail").Value),
DatePublished = item.Attribute("ows_Date_Published").Value,
PublishedBy = item.Attribute("ows_PublishedBy").Value,
}).Take(items);
this.DataContext = _StaffNews;
//NewsList.SelectedIndex = -1;
}

Categories

Resources