Bind XML data to a Dropdownlist c# - c#

I am trying to bind XML data to Dropdownlist
XElement xDoc = XElement.Parse(QContent.OuterXml);
Here is what my xDoc contains
<root xmlns="">
<item value="-1" text="Select" />
<item value="1" text="$30,000" />
<item value="2" text="$50,000" />
</root>
Query to extract the data into a Listitem :
var query = from xEle in xDoc.Descendants("root")
select new ListItem(xEle.Attribute("value").Value , xEle.Attribute("text").Value);
This yields no results. Please advice.
Thanks in advance
BB

Put your XML file inside App_Data or anywhere in program and in MapPath.
Assign their path and also assign the name of your first XML column in the last line.
Here I'm using "code" because it is my first XML column and country is the name of the column I want to show in my dropdownlist.
private void BindCountry()
{
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("~//App_Data//countries.xml"));
foreach (XmlNode node in doc.SelectNodes("//country"))
{
ddlcountry.Items.Add(new ListItem(node.InnerText, node.Attributes["code"].InnerText));
}
}

You can change your LINQ query to the following which will return all the nodes under root and return new items with the value/text pairs that you are trying to bind to.
var query = from xEle in xDoc.Descendants()
select new {value = xEle.Attribute("value").Value , text = xEle.Attribute("text").Value};
Then set up your bindings as follows including collapsing the query to a list.
ddlList.DataValueField = "value";
ddlList.DataTextField = "text";
ddlList.DataSource = query.ToList();
ddlList.DataBind();

Related

System.Xml.Linq.XContainer.Element(…) returned null while trying to load XML file into ListView

I'm trying to load an XML file into a ListView, however, every time I select the file, I get an error which says
System.Xml.Linq.XContainer.Element(…) returned null
This is my code:
XDocument doc = XDocument.Load(typesXML);
IEnumerable<XElement> serverElements = doc.Descendants("type");
foreach (XElement serverElement in serverElements)
{
ListViewItem item = new ListViewItem(new string[]
{
serverElement.Element("nominal").Value,
serverElement.Element("lifetime").Value,
serverElement.Element("restock").Value,
serverElement.Element("min").Value,
serverElement.Element("quantmin").Value,
serverElement.Element("quantmax").Value,
serverElement.Element("cost").Value
});
listView1.Items.Add(item);
}
XML:
<types>
<type name="ACOGOptic">
<nominal>15</nominal>
<lifetime>7200</lifetime>
<restock>1800</restock>
<min>8</min>
<quantmin>-1</quantmin>
<quantmax>-1</quantmax>
<cost>100</cost>
<flags count_in_cargo="0" count_in_hoarder="0" count_in_map="1" count_in_player="0" crafted="0" deloot="0"/>
<category name="weapons"/>
<usage name="Military"/>
</type>
</types>
Also, how would I go when I also want the tag "name" from "type" load into my ListView?
It worked with using DataSet, but I want to use it like this.

How to the replace node names with new name and keep the attributes using C# and Linq to XML?

I need to change
<Test Language="English" Id="0" />
to
<Exam Language="English" Id="0" />
How to the replace node names with new name and keep the attributes ?
You can use Name property
var xdoc = XDocument.Load("input.xml");
var nodes=xdoc.Descendants("Test").ToList();//Get all "Test" node
nodes.ForEach(d => d.Name = "Exam "); // Set name to 'Exam'
xdoc.Save("output.xml");

List is empty after parsing XML with LinQ

I have an xml file similar to the following:
<doc>
<file>
<header>
<source>
RNG
</source>
</header>
<body>
<item name="items.names.id1">
<property>propertyvalue1</property>
</item>
<!-- etc -->
<item name="items.names.id100">
<property>propertyvalue100</property>
</item>
<!-- etc -->
<item name="otheritems.names.id100">
<property>propertyvalue100</property>
</item>
</body>
</file>
</doc>
And the following class:
private class Item
{
public string Id;
public string Property;
}
The file has, for example, 100 item entries (labeled 1 to 100 in the name attribute). How can I use Linq Xml to get hold of these nodes and place them a in list of item?
Using Selman22's example, I'm doing the following:
var myList = xDoc.Descendants("item")
.Where(x => x.Attributes("name").ToString().StartsWith("items.names.id"))
.Select(item => new Item
{
Id = (string)item.Attribute("name"),
Name = (string)item.Element("property")
}).ToList();
However, the list is empty. What am I missing here?
Using LINQ to XML:
XDocument xDoc = XDocument.Load(filepath);
var myList = xDoc.Descendants("item").Select(item => new Item {
Id = (string)item.Attribute("name"),
Property = (string)item.Element("property")
}).ToList();
You can use LinqToXml to directly query the XML, or deserialize it and use LINQ to object. If you choose to deserialize I suggest to start from the schema and generate the classes representing your datamodel with xsd.exe. If you don't have the schema of your xml, even xsd.exe can infer one from an example xml file, but you probably need to fine tune the result.
Try this one XElement root = XElement.Parse("your file name");
var items textSegs =(from item in root.Descendants("item")
select item).ToList();
Now iterate over list and store it
The below is a way of getting information from xml using Xdocument.
string input = "<Your xml>";
Xdocument doc = XDocument.Parse(input);
var data = doc.Descendants("item");
List<Items> itemsList = new List<Items>();
foreach(var item in data)
{
string itemname= item.Element("item").Value;
string property = item.Element("property").Value;
itemsList.Add(new item(itemname, property));
}
I'm guessing you want the code given how your question is phrased.. also I'm assuming the real XML is very simplistic as well.
var items = from item in doc.Descendants("item")
select new Item()
{
Id = item.Attributes("name").First().Value,
Property = item.Elements().First().Value,
};
Just ensure that your xml is loaded into doc. You can load the xml in two ways:
// By a string with xml
var doc = XDocument.Parse(aStringWithXml);
// or by loading from uri (file)
var doc = XDocuemnt.Load(aStringWhichIsAFile);

Read xml file and write ids' values into related textbox in C#

I have a xml file named "numbers.xml" like this:
<?xml version="1.0" encoding="utf-8" ?>
<program>
<box id="aaa" value="78678"/>
<box id="bbb" value="37287"/>
<box id="ccc" value="783"/>
<box id="ddd" value="7867"/>
<box id="eee" value="786"/>
<box id="fff" value="23"/>
<box id="ggg" value="453"/>
<box id="hhh" value="4537"/>
</program>
I want to read this xml file and fill textboxes. But in windows forms application txtAAA.text value must take id="aaa" value which is 78678. Likewise txtBBB.text value must take id="bbb" value which is 37287.
How can I do this?
Edit:
I tried like this:
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(openfiledialog1.FileName);
XmlNodeList nodelist = xmldoc.DocumentElement.ChildNodes;
XmlNode xmlnode = nodelist.Item(0);
txtAAA.Text = xmlnode.Attributes["id"].InnerText;
But "aaa" is shown in textbox. It was totally failure. –
nMaybe this line of code will help you:
TextBox textBox = this.Controls.OfType<TextBox>().FirstOrDefault(tb => tb.Name == "idFromXMl");
In your case, where you have more textboxes I would save the result of this.Controls.OfType<TextBox>() in a collection and the work on with this.
You could create a list of the xml items and assign the based on the TextBox name in a foreach loop
Assuming TextBox names are:
txtAAA
txtBBB
txtCCC
...etc
you can just remove the txt part to find the correct value id
var data = XElement.Load("C:\\Test.xml").Descendants("box");
foreach (var textbox in Controls.OfType<TextBox>())
{
var value = data.FirstOrDefault(v => v.Attribute("id").Value == textbox.Name.Replace("txt","").ToLower());
if (value != null)
{
textbox.Text = value.Attribute("value").Value;
}
}
Test:
You can use XPath to find the node.
Then find the attribute, 'value'.
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load( openfiledialog1.FileName );
XmlNode nodeAAA = xmldoc.SelectSingleNode( "/program/box[#id='aaa']" ); //XPath Query here.
txtAAA.Text = nodeAAA.Attributes["value"].InnerText;
XPath Tutorial - http://www.w3schools.com/xpath/xpath_syntax.asp

Find frequency of values in an Array or XML (C#)

I have an XML feed (which I don't control) and I am trying to figure out how to detect the volume of certain attribute values within the document.
I am also parsing the XML and separating attributes into Arrays (for other functionality)
Here is a sample of my XML
<items>
<item att1="ABC123" att2="uID" />
<item att1="ABC345" att2="uID" />
<item att1="ABC123" att2="uID" />
<item att1="ABC678" att2="uID" />
<item att1="ABC123" att2="uID" />
<item att1="XYZ123" att2="uID" />
<item att1="XYZ345" att2="uID" />
<item att1="XYZ678" att2="uID" />
</items>
I want to find the volume nodes based on each att1 value. Att1 value will change. Once I know the frequency of att1 values I need to pull the att2 value of that node.
I need to find the TOP 4 items and pull the values of their attributes.
All of this needs to be done in C# code behind.
If I was using Javascript I would create an associative array and have att1 be the key and the frequency be the value. But since I'm new to c# I don't know how to duplicate this in c#.
So I believe, first I need to find all unique att1 values in the XML. I can do this using:
IEnumerable<string> uItems = uItemsArray.Distinct();
// Where uItemsArray is a collection of all the att1 values in an array
Then I get stuck on how I compare each unique att1 value to the whole document to get the volume stored in a variable or array or whatever data set.
Here is the snippet I ended up using:
XDocument doc = XDocument.Load(#"temp/salesData.xml");
var topItems = from item in doc.Descendants("item")
select new
{
name = (string)item.Attribute("name"),
sku = (string)item.Attribute("sku"),
iCat = (string)item.Attribute("iCat"),
sTime = (string)item.Attribute("sTime"),
price = (string)item.Attribute("price"),
desc = (string)item.Attribute("desc")
} into node
group node by node.sku into grp
select new {
sku = grp.Key,
name = grp.ElementAt(0).name,
iCat = grp.ElementAt(0).iCat,
sTime = grp.ElementAt(0).sTime,
price = grp.ElementAt(0).price,
desc = grp.ElementAt(0).desc,
Count = grp.Count()
};
_topSellers = new SalesDataObject[4];
int topSellerIndex = 0;
foreach (var item in topItems.OrderByDescending(x => x.Count).Take(4))
{
SalesDataObject topSeller = new SalesDataObject();
topSeller.iCat = item.iCat;
topSeller.iName = item.name;
topSeller.iSku = item.sku;
topSeller.sTime = Convert.ToDateTime(item.sTime);
topSeller.iDesc = item.desc;
topSeller.iPrice = item.price;
_topSellers.SetValue(topSeller, topSellerIndex);
topSellerIndex++;
}
Thanks for all your help!
Are you using .NET 3.5? (It looks like it based on your code.) If so, I suspect this is pretty easy with LINQ to XML and LINQ to Objects. However, I'm afraid it's not clear from your example what you want. Do all the values with the same att1 also have the same att2? If so, it's something like:
var results = (from element in items.Elements("item")
group element by element.Attribute("att1").Value into grouped
order by grouped.Count() descending
select grouped.First().Attribute("att2").Value).Take(4);
I haven't tested it, but I think it should work...
We start off with all the item elements
We group them (still as elements) by their att1 value
We sort the groups by their size, descending so the biggest one is first
From each group we take the first element to find its att2 value
We take the top four of these results
If you have the values, you should be able to use LINQ's GroupBy...
XDocument doc = XDocument.Parse(xml);
var query = from item in doc.Descendants("item")
select new
{
att1 = (string)item.Attribute("att1"),
att2 = (string)item.Attribute("att2") // if needed
} into node
group node by node.att1 into grp
select new { att1 = grp.Key, Count = grp.Count() };
foreach (var item in query.OrderByDescending(x=>x.Count).Take(4))
{
Console.WriteLine("{0} = {1}", item.att1, item.Count);
}
You can use LINQ/XLINQ to accomplish this. Below is a sample console application I just wrote, so the code might not be optimized but it works.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Text;
namespace FrequencyThingy
{
class Program
{
static void Main(string[] args)
{
string data = #"<items>
<item att1=""ABC123"" att2=""uID"" />
<item att1=""ABC345"" att2=""uID"" />
<item att1=""ABC123"" att2=""uID"" />
<item att1=""ABC678"" att2=""uID"" />
<item att1=""ABC123"" att2=""uID"" />
<item att1=""XYZ123"" att2=""uID"" />
<item att1=""XYZ345"" att2=""uID"" />
<item att1=""XYZ678"" att2=""uID"" />
</items>";
XDocument doc = XDocument.Parse(data);
var grouping = doc.Root.Elements().GroupBy(item => item.Attribute("att1").Value);
foreach (var group in grouping)
{
var groupArray = group.ToArray();
Console.WriteLine("Group {0} has {1} element(s).", groupArray[0].Attribute("att1").Value, groupArray.Length);
}
Console.ReadKey();
}
}
}

Categories