Reputation: 15545
Probably this question repeated, but i am not satiesfied with existing answers. I want to get xml element from dynamically generated xml file by attribute value. we don't know how many nodes, and its herarchy. but each element, its sub element, its sub-sub elements, sub-sub-sub elements...so on will contain unique guid as "Id" attribute :
<Element id="">
<SubElement id=""></SubElement>
<SubElement id="">
<SubSubElement id="">
<SubSubSubElement id="">
<SubSubSubSubElement id="">....other sub inside this ...</SubSubSubSubElement>
</SubSubSubElement>
</SubSubElement>
</SubElement>
</Element>
I want to find the element by only passing the Guid value. nonethless of its xpath, its node location / position. how can i do this in C#? is i need to use LINQ?
Edited:
XDocument xmldoc = XDocument.Load(xmlFilePath);
XElement selectedElement = xmldoc.Descendants().Where(x => (string) x.Attribute("id") == myIdvalue).FirstOrDefault();
Exception : "Expression cannot contain lambda expressions" I have added Using System.Linq namspaces.
Upvotes: 10
Views: 17040
Reputation: 1500635
hoipolloi has given an XPath answer, which is fine - but I would personally use LINQ to XML. (See my blog post on code and data for reasons.)
var element = parent.Descendants()
.Where(x => (Guid?) x.Attribute("id") == id)
.FirstOrDefault();
This will perform appropriate GUID parsing on each id
attribute (returning a "null" Guid?
value for non-GUIDs). If you're certain of the text format of your ID, you can cast to string instead:
var element = parent.Descendants()
.Where(x => (string) x.Attribute("id") == idText)
.FirstOrDefault();
Change the FirstOrDefault
to Single
, SingleOrDefault
or First
depending on your requirements.
EDIT: It's not at all clear what's going wrong with the code you've posted. Here's a short but complete program which shows it working fine. Please compare this with your code:
using System;
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
string xml = "<parent><foo id='bar' /><foo id='baz' /></parent>";
XDocument doc = XDocument.Parse(xml);
string idToFind = "bar";
XElement selectedElement = doc.Descendants()
.Where(x => (string) x.Attribute("id") == idToFind).FirstOrDefault();
Console.WriteLine(selectedElement);
}
}
Upvotes: 12
Reputation: 8044
You can use XPath to do this. For instance, the following matches all elements with an id of 'foo', irrespective of their location in the document:
//*[@id='foo']
Upvotes: 5