Getting Attribute's value from xml in c# - c#

I have a LINQ expression which gets the XML attribute values from a xml file.
var xml = XElement.Load(#"C:\\StoreServer1.xml");
var query = from e in xml.Descendants("Groups")
where int.Parse(e.Element("Store").Value) == 1500
select e.Element("Store").Attribute("WeekDayStClose").Value;
And the xml file is:
enter<?xml version="1.0" encoding="utf-8" ?>
<Stores>
<Groups Range="000">
<Store WeekDayStClose="210" SatStClose="21" SunStClose="22">1500</Store>
<Store WeekDayStClose="23" SatStClose="24" SunStClose="25">18</Store>
<Store WeekDayStClose="23" SatStClose="24" SunStClose="25">19</Store>
</Groups>
</Stores>
I am only getting the attribute result (value) for first element of 1500. If I search same thing for 18 it doesn't return any result and no exception. Any help appreciated....Plz help!!!

Try this out:-
var xml = XElement.Load(#"C:\\StoreServer1.xml");
var query = xml.Descendants("Groups").Descendants("Store").Where(e => int.Parse(e.Value) == 18).Select(e=> e.Attribute("WeekDayStClose").Value);

You should be more granular, call sub Descendants with Store (XName):
var xml = XElement.Load(#"C:\\New Folder\\StoreServer1.xml");
var query = from e in xml.Descendants("Groups").Descendants("Store")
where int.Parse(e.Value) == 18
select e.Attribute("WeekDayStClose").Value;
Because now you're retrieving only the first Store of each Group which is 1500.

Yes, you have a little error in your code:
You are splitting your xml into group-elements (you have just one group). Then you check if the first store element has the value 1500 (you are not checking if the following store elements have maybe the value 1500)
You need to change your code into the following
var query = from e in xml.Descendants("Store")
where int.Parse(e.Value) == 1500
select e.Attribute("WeekDayStClose").Value;

Related

C# Lambda Method syntax to obtain attribute values that match pattern in LINQ to XML

I have the following XML fragment and would like to pull out the values of the status attributes that are not zero. I can obtain the elements that match the criteria but what I really want is the values of the status attributes.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<Auth status = "0">Moo</Auth>
<Add status = "817">Cow</Add>
<Add status = "888">Brown</Add>
<Add status = "123">Dog</Add>
</response>
This lambda syntax brings back a list of the matching elements but what I need is a list of the status values not a list of the elements with those values.
var errcodeList = xml.Descendants("Add").Where(x => x.Attribute("status").Value != "0").Attributes("status");
When you use Select, you are projecting the IEnumerable into another form, in this case it's a list of x.Attributes("status").Value
var errcodeList = xml.Descendants("Add")
.Where(x => x.Attribute("status").Value != "0")
.Select(x => x.Attributes("status").Value);
You can use Select to project the collection to the specific results that you want. For example:
var errcodeList = xml.Descendants("Add").Where(x => x.Attribute("status").Value != "0").Select(x => x.Attribute("status").Value);

i want to fetch array of record in xml using c# Linq

this is my code to fetch xml values from files and it does successfully but single element like an in file type but when i try to fetch array of records from xml it failed
public void readXmlFiles()
{
var xml = XDocument.Load(#"C:\Applications\Files\Xmldemo.xml");
var format = from r in xml.Descendants("insureance")
select new
{
type = r.Element("type").Value,
// values=r.Element("value").Value
};
foreach (var r in format)
{
Console.WriteLine(r.values);
}
}
this is my xml file
<?xml version="1.0" encoding="UTF-8"?>
<insureance>
<type>Risk</type>
<classofbusiness type="array">
<value>0</value>
<value>1</value>
<value>2</value>
</classofbusiness>
</insureance>
now i want to fetch classofbusiness all values thanx in advance
Your current attempt selects a single value element, which doesn't exist as a child of insureance. I would guess you get a null reference exception as a result.
You need to follow the structure of the document
var format =
from ins in doc.Descendants("insureance")
select new
{
Type = (string) ins.Element("type"),
ClassOfBusiness = ins.Elements("classofbusiness")
.Elements("value")
.Select(x => (int) x)
.ToArray()
};
var format = xml.Elements("insureance").Elements("classofbusiness").Descendants();

XML data filtering and searching

I have the following chunk of XML code that I can easily generate.
<?xml version="1.0" encoding="utf-8"?>
<sessions>
<session date="14.10.2016" time="0:1" amount="1">
<Folder>C:\Users</Folder>
<Folder>C:\Tes2t</Folder>
<Folder>C:\Asgbsf\Aleksei</Folder>
</session>
<session date="14.10.2016" time="15:40" amount="7">
<Folder>C:\Users</Folder>
<Folder>C:\Tes2taaaa</Folder>
<Folder>C:\Asgbsf\Aleksei</Folder>
</session>
</sessions>
I am searching for data with attribute time 15:40 and date 14.10.2016 using following function
private static IEnumerable<XElement> FindElements(string filename, string date, string time)
{
XElement x = XElement.Load(filename);
return x.Descendants().Where(e => e.Attributes("date").Any(a => a.Value.Equals(date)) &&
e.Attributes("time").Any(a => a.Value.Equals(time)));
}
Function being executed like:
foreach (XElement x in FindElements(pathToXml, "14.10.2016", "15:40"))
Console.WriteLine(x.ToString());
Everything is fine, but the output is
<session date="14.10.2016" time="15:40" amount="7">
<Folder>C:\Users</Folder>
<Folder>C:\Tes2taaaa</Folder>
<Folder>C:\Asgbsf\Aleksei</Folder>
</session>
And I need just the folders, eg.
<Folder>C:\Users</Folder>
<Folder>C:\Tes2taaaa</Folder>
<Folder>C:\Asgbsf\Aleksei</Folder>
How do I achieve this? Help please.
(It seems that I am a little bit late, but..) in some cases like this using Xpath is easier than Linq .
var folders = XDocument.Load(filename)
.XPathSelectElements("//session[#dat‌​e='14.10.2016' and #time='15:40']/Folder");
You are currently returning the Element that has attribute of date and time with these values. What you should add to it is to return its child elements of Folder. You can do this by adding .Elements("Folder") after the .Where.
However, I think you can write your query a bit nicer:
Look for all the sessions that the values of those attriute equal to the given input. Then return the element.Elements("Folder").
I've added the .SelectMany() to flatten the inner list of child elements
string date = "14.10.2016";
string time = "15:40";
var result = (from element in XDocument.Load("data.xml").Descendants("session")
where element.Attribute("date")?.Value == date &&
element.Attribute("time")?.Value == time
select element.Elements("Folder")).SelectMany(item => item).ToList();

Simple XML parsing with LINQ

I would like to parse this XML :
<?xml version="1.0" encoding="Windows-1252" ?>
<TEST>Login inexistant</TEST>
I wrote this code
var result = from item in XElement.Parse(m_strRetour).Descendants("TEST")
select item;
return result.First().ToString();
m_strRetour is a string that contains my XML.
After execution, result is empty.
What am I doing wrong?
TEST seems to be your root node, so it can't be a Descendant.
To get the value out of it you could try this.
var xml = "<?xml version='1.0' encoding='Windows-1252' ?><TEST>Login inexistant</TEST>";
var result = XElement.Parse(xml);
var value = result.Value;
XElement.Parse will return the TEST element itself - which doesn't have any descendants. (Also, there's no benefit in using a query expression here. Whenever you write from x in y select x you should consider whether you couldn't just use y instead...)
You could parse it as an XDocument instead, in which case there would be a TEST descendant... or you could just use the XElement itself.
What are you really trying to achieve though? Does your real XML only have a single element?

Linq to XML retrieve single node

I have the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<game>
<name>Space Blaster</name>
<description></description>
<version>1</version>
<fullscreen>false</fullscreen>
<width>640</width>
<height>640</height>
<c2release>6900</c2release>
</game>
It's guaranteed to only have 1 game record in it. I'd like to retrieve each property value, this is what I've tried:
string ArcadeXMLLocation = Settings.GamePergatoryLocation + UserID + "/unzipped/arcade.xml";
XDocument loaded = XDocument.Load(ArcadeXMLLocation);
var q = (from c in loaded.Descendants("game") select (string)c.Element("name")).SingleOrDefault();
Response.Write(q.name);
But I can't seem to take any values like this (intellisense hates it!) Can someone show me how it's done?
I think you just need to get the value of the element:
string val = doc.Descendants("game")
.Select(x => x.Element("name").Value).FirstOrDefault();
As a prerequisite to the above, and so intellisense picks it up, make sure that you import the System.Linq and System.Xml.Linq namespaces.
This will get you all the descendants with the tag "game"
You just need the FirstOrDefault() to get the only record if it exists.
var q = from c in loaded.Descendants("game")
select new { Name = c.Element("name").Value
Description = c.Element("description").Value
};
q.FirstOrDefault();
You query is actually correct (tested and worked for me) for extracting the value of the name node - the (string) cast that you are doing will extract the value of the name node as string and not give you the node object itself, this is one of the shortcuts built into Linq to Xml. All that is left is to print out the name:
Response.Write(q);
var q = (from c in loaded.Descendants("game") select (string)c.Element("name")).SingleOrDefault();
Console.WriteLine(q);
is enough. or to avoid the cast
var q = (from c in loaded.Descendants("game") select c.Element("name").Value).SingleOrDefault();
Console.WriteLine(q);

Categories