简体   繁体   中英

Getting attribute name from xml in c#

I get a XML - File like this:

<list>
<sublist id1="a" id2="b" id3="b" id4="b">
    <item name="name1">
        <property1>a</property1>
     </item>
    <item2 name="name2">
        <property1>c</property1>
    </item2>
</sublist>
<sublist id1="b" id2="b" id3="a" id4="b">        
 [...more XML here...]
</sublist>

How can I find out the attribute name of the element "sublist" with the value "a" ?

If you have the XML string in a variable called xml :

XDocument
  .Parse(xml)                      // parse the XML
  .Descendants()                   // get all descendant elements
  .SelectMany(e => e.Attributes()) // get all attributes from all elements
  .Where(a => a.Value == "a")      // leave only attributes whose value is "a"
  .Select(a => a.Name);            // select the name of those attributes

The result:

id1
id3

Note that this code uses XElement and LINQ to accomplish the goal. There are many other ways, some of which may be better suited to your needs.

Update

I noticed now that you're only looking for attributes on sublist elements. The code can be modified to handle that:

XDocument
  .Parse(xml)                      // parse the XML
  .Descendants("sublist")          // get all descendant elements named "sublist"
  .SelectMany(e => e.Attributes()) // get all attributes from all elements
  .Where(a => a.Value == "a")      // leave only attributes whose value is "a"
  .Select(a => a.Name);            // select the name of those attributes

The difference is in the call to Descendants , which now filters out any elements that is not called sublist .

In a comment you also asked how to handle the case when there is just a single sublist element. The code snippets above work fine for that too, since they're not making any assumptions about the number of elements.

You might be tempted to handle that case differently, such as with this code:

XDocument
  .Parse(xml)                      // parse the XML
  .Descendants("sublist")          // get all descendant elements named sublist
  .Single()                        // get the one and only element
  .Attributes()                    // get all attributes from all elements
  .Where(a => a.Value == "a")      // leave only attributes whose value is "a"
  .Select(a => a.Name)             // select the name of those attributes

The difference between this and the previous examples is that we use Single here to extract the one and only sublist element from the result. The item type in the code at that point becomes XElement , and Single will throw an exception if there are no ("Sequence contains no elements") or more than one ("Sequence contains more than one element") sublist elements. In the next line we can then get rid of the SelectMany call and just access the Attributes of the XElement straight away.

But in my opinion the change in the code is not worth the loss in robustness you'll have.

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