135

Suppose I have a XmlNode and I want to get the value of an attribute named "Name". How can I do that?

XmlTextReader reader = new XmlTextReader(path);

XmlDocument doc = new XmlDocument();
XmlNode node = doc.ReadNode(reader);

foreach (XmlNode chldNode in node.ChildNodes)
{
     **//Read the attribute Name**
     if (chldNode.Name == Employee)
     {                    
         if (chldNode.HasChildNodes)
         {
             foreach (XmlNode item in node.ChildNodes)
             { 

             }
         }
      }
}

XML Document:

<Root>
    <Employee Name ="TestName">
    <Childs/>
</Root>
AlexINF
  • 250
  • 2
  • 11
Ashish Ashu
  • 14,169
  • 37
  • 86
  • 117

8 Answers8

237

Try this:

string employeeName = chldNode.Attributes["Name"].Value;

Edit: As pointed out in the comments, this will throw an exception if the attribute doesn't exist. The safe way is:

var attribute = node.Attributes["Name"];
if (attribute != null){
    string employeeName = attribute.Value;
    // Process the value here
}
Konamiman
  • 49,681
  • 17
  • 108
  • 138
  • 37
    Be careful with this approach. I think if the attribute is not present, then accessing the Value member will cause a Null Reference Exception. – Chris Dunaway Oct 21 '09 at 14:06
  • 3
    if(node.Attributes != null) string employeeName = chldNode.Attributes["Name"].Value; – Omidoo Sep 28 '12 at 23:03
  • 7
    @Omidoo That approach has the same issue, for example with ``, which passes the test. Perhaps something like `var attr = node.Attributes["Name"]; if(attr != null) {...}` might work. – Joel Peltonen Nov 13 '12 at 12:00
  • Take a look at [my answer below](http://stackoverflow.com/a/37322614/1139514), which circumvents the NullException problem and is, maybe?, safer to use. – Marco7757 May 19 '16 at 12:03
  • An updated answer could be string employeeName = chldNode.Attributes["Name"]?.Value; – jing May 11 '22 at 08:37
45

To expand Konamiman's solution (including all relevant null checks), this is what I've been doing:

if (node.Attributes != null)
{
   var nameAttribute = node.Attributes["Name"];
   if (nameAttribute != null) 
      return nameAttribute.Value;

   throw new InvalidOperationException("Node 'Name' not found.");
}
Ari Roth
  • 5,392
  • 2
  • 31
  • 46
  • 7
    A shorthand way of not getting an error for nulls is node.Attributes?["Name"]?.Value – brandonstrong Mar 02 '17 at 19:51
  • 1
    Also true, though the only thing I'll point out is that while you can do that in one line (making it good for an assignment or something), it's a bit less flexible in terms of controlling when you throw an exception or otherwise handle the case where node has no attributes. – Ari Roth Mar 03 '17 at 00:28
  • 1
    Agreed. Anyone who uses the shorthand way should always make sure it won't cause problems downstream. – brandonstrong Mar 03 '17 at 20:13
17

you can loop through all attributes like you do with nodes

foreach (XmlNode item in node.ChildNodes)
{ 
    // node stuff...

    foreach (XmlAttribute att in item.Attributes)
    {
        // attribute stuff
    }
}
balexandre
  • 73,608
  • 45
  • 233
  • 342
6

If you use chldNode as XmlElement instead of XmlNode, you can use

var attributeValue = chldNode.GetAttribute("Name");

The return value will just be an empty string, in case the attribute name does not exist.

So your loop could look like this:

XmlDocument document = new XmlDocument();
var nodes = document.SelectNodes("//Node/N0de/node");

foreach (XmlElement node in nodes)
{
    var attributeValue = node.GetAttribute("Name");
}

This will select all nodes <node> surrounded by <Node><N0de></N0de><Node> tags and subsequently loop through them and read the attribute "Name".

Marco7757
  • 735
  • 9
  • 16
4

if all you need is the names, use xpath instead. No need to do the iteration yourself and check for null.

string xml = @"
<root>
    <Employee name=""an"" />
    <Employee name=""nobyd"" />
    <Employee/>
</root>
";

var doc = new XmlDocument();

//doc.Load(path);
doc.LoadXml(xml);

var names = doc.SelectNodes("//Employee/@name");
an phu
  • 1,823
  • 1
  • 16
  • 10
3

Use

item.Attributes["Name"].Value;

to get the value.

Cindy Meister
  • 25,071
  • 21
  • 34
  • 43
rahul
  • 184,426
  • 49
  • 232
  • 263
1

You can also use this;

string employeeName = chldNode.Attributes().ElementAt(0).Name
cell-in
  • 709
  • 2
  • 11
  • 27
1

Yet another solution:

string s = "??"; // or whatever

if (chldNode.Attributes.Cast<XmlAttribute>()
                       .Select(x => x.Value)
                       .Contains(attributeName))   
   s =  xe.Attributes[attributeName].Value;

It also avoids the exception when the expected attribute attributeName actually doesn't exist.

TaW
  • 53,122
  • 8
  • 69
  • 111