1

I have the following XML

<?xml version="1.0" encoding="UTF-8"?>
<xmlarchivefieldlist archive_schema="47800727">
   <client key_id="47800731"  str_label="Customer" str_type="select" invoice="1"/>
   <brand key_id="47800734" str_label="BrandName" str_type="text" invoice="2"/>
   <product key_id="47800730" str_label="Product" str_type="text" invoice="3"/>
</xmlarchivefieldlist>

I have the document in an XDocument.

How do I find the Element name when I know only an Attribute value.

e.g. I know str_label="Customer" so I want returned:- client. e.g. I know str_type="text" so I want returned:- brand, product.

Richard210363
  • 8,342
  • 6
  • 37
  • 63
  • Take a look at this post seems to be very similar to your question, http://stackoverflow.com/questions/2678251/find-elements-by-attribute-using-xdocument. – Bearcat9425 Nov 04 '13 at 15:23
  • No I read that one. It already know the element name. I'm looking for the element name – Richard210363 Nov 04 '13 at 15:25

5 Answers5

3

You can use LINQ to XML with XPath to get element by attribute value:

var xdoc = XDocument.Load(path_to_xml);
var names = xdoc.XPathSelectElements("//*[@str_label='Customer']")
                .Select(e => e.Name);

Or you can use lambda syntax:

string attrName = "str_type";
string attrValue = "text";
var names = xdoc.Descendants()
                .Where(e => (string)e.Attribute(attributeName) == attrValue)
                .Select(e => e.Name);

BTW: To get concatenated string with names you can use String.Join:

var result = String.Join(",", names);
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
1
xdoc.Descendants()
    .Where(x => x.Attribute("str_label") != null
              && x.Attribute("str_label").Value == "Customer")
    .Select(e => e.Name);
decPL
  • 5,384
  • 1
  • 26
  • 36
  • 1
    I suggest you to use explicit casting operator to get nullable types from attributes or elements - that will allow to skip null-check and getting value – Sergey Berezovskiy Nov 04 '13 at 15:29
0

You want .Attribute("str_label").Value

Something like:

var filter = xDoc.Descendents("xmlarchivefieldlist").Where(x => (string)x.Attribute("str_label") == "Customer");
Sam Leach
  • 12,746
  • 9
  • 45
  • 73
0

If you know that the root element is <xmlarchivefieldlist> and that the element you're looking for is a child of that, you can do this:

var customer = doc.Element("xmlarchivefieldlist").Elements()
            .FirstOrDefault(x => x.Attribute("str_label").Value == "Customer");
Console.WriteLine(customer);
<client key_id="47800731" str_label="Customer" str_type="select" invoice="1" />

To more generally look for any descendant elements that match, you can just do the following. This, unlike the above, does not require the elements it's looking at to have a str_label attribute.

var customer = doc.Descendants()
            .FirstOrDefault(x => (string)x.Attribute("str_label") == "Customer");
Console.WriteLine(customer);
Tim S.
  • 55,448
  • 7
  • 96
  • 122
0

Xpath:

name(//node()[@str_label='Customer'][1])

Will return the node-name 'client'

Jasper
  • 534
  • 3
  • 11