Linq to XML simple get attribute from node statement
Solution 1
I think you want something closer to this:
XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml"));
string result = "";
var childType = from t in themes.Descendants("theme")
where t.Attribute("name").Value.Equals(theme)
select new { value = t.Descendants().Attribute("type").Value };
foreach (var t in childType) {
result += t.value;
}
return result;
EDIT: Based on your additional info, perhaps this is even closer:
XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml"));
string result = "";
var childType = from t in themes.Descendants("theme")
where t.Attribute("name").Value.Equals(theme)
where t.Element("node").Attribute("type").Value == parent
select new { value = t.Descendants().Attribute("type").Value };
foreach (var t in childType) {
result += t.value;
}
return result;
EDIT 2: This is working for me:
XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml"));
string result = "";
var theme = "Agile";
var parent = "Project";
var childType = from t in themes.Descendants("theme")
where t.Attribute("name").Value.Equals(theme)
where t.Element("root").Attribute("type").Value == parent
from children in t.Element("root").Descendants()
select new { value = children.Attribute("type").Value };
foreach (var t in childType) {
result += t.value;
}
return result;
EDIT 3: Here's the complete working program, just throw it in a class in a console application.
static void Main(string[] args)
{
var xml = "<themes><theme name='Agile'><root type='Project'><node type='Iteration' ><node type='Story'><node type='Task'/></node></node></root></theme><theme name='Release' ><root type='Project'><node type='Release'><node type='Task' /><node type='Defect' /></node></root></theme></themes>";
XDocument themes = XDocument.Parse(xml);
string result = "";
var theme = "Agile";
var parent = "Project";
var childType = from t in themes.Descendants("theme")
where t.Attribute("name").Value.Equals(theme)
where t.Element("root").Attribute("type").Value == parent
from children in t.Element("root").Descendants()
select new { value = children.Attribute("type").Value };
foreach (var t in childType)
{
Console.WriteLine(t.value);
}
Console.Read();
}
Solution 2
Ok here's what I did in the end, it's not very pretty but it works. Its based on the answer by Pramodh with a few tweeks.
string result = "";
var childType = themes.Descendants("theme")
.Where(x => x.Attribute("name").Value == theme)
.Where(x => x.Descendants("node").First().Attribute("type").Value == parentType)
.Select(x => x.Descendants("node").First().Descendants().First().Attribute("type").Value);
foreach (var t in childType) {
result += t;
}
return result;
now if I pass in theme "Agile" and parent "Iteration" it returns story.
Like I said not very pretty but it works.
Thank you to everyone who posted answers.
Morgeh
Web developer for Next-Plc currently working on Lipsy.co.uk. I graduate from Staffordshire University with a 2.1 in Computing Science. In my spare time I work on www.thedevgame.com and enjoy gaming and creating mods for games.
Updated on June 15, 2022Comments
-
Morgeh about 2 years
Here's the code snippet:
XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml")); string result = ""; var childType = from t in themes.Descendants() where t.Attribute("name").Value.Equals(theme) select new { value = t.Attribute("type").Value }; foreach (var t in childType) { result += t.value; } return result;
and here's the XML:
<?xml version="1.0" encoding="utf-8" ?> <themes> <theme name="Agile"> <root type="Project"> <node type="Iteration" > <node type="Story"> <node type="Task"/> </node> </node> </root> </theme> <theme name="Release" > <root type="Project"> <node type="Release"> <node type="Task" /> <node type="Defect" /> </node> </root> </theme> </themes>
What am I doing wrong? I keep getting an "object not set to an instance of an object" exception.
What I'm trying to return is the type of the selected node based on the type of a parent node, i.e., if the theme is "Agile" and the parent node is "Project" then the return value should be "Iteration". That's the final outcome but I never got that far because I got stuck with what you see above.
-
Morgeh over 13 yearsthere isn't a method version of FirstNode its a property that doesn't have an attribute method.
-
Morgeh over 13 yearsI had to add .First() to t.Descendants() within the select statement to get it to compile, however I'm still getting object not set to an instance of an object exceptions
-
Morgeh over 13 yearsyour 2nd edit is returning blank values for me. I couldn't be to do with the layout of my xml could it?
-
Chris Conway over 13 yearsI've updated again showing the complete working example based on what you've given. If it's still not working, take a look at your xml and make sure it's the same format as what I have. It should be working for you unless there's something else in the xml.