简体   繁体   中英

access xml element by attribute value

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.

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);
    }
}

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']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM