142

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>

9 Answers 9

244

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
}
Sign up to request clarification or add additional context in comments.

5 Comments

Be careful with this approach. I think if the attribute is not present, then accessing the Value member will cause a Null Reference Exception.
if(node.Attributes != null) string employeeName = chldNode.Attributes["Name"].Value;
@Omidoo That approach has the same issue, for example with <a x="1" />, which passes the test. Perhaps something like var attr = node.Attributes["Name"]; if(attr != null) {...} might work.
Take a look at my answer below, which circumvents the NullException problem and is, maybe?, safer to use.
An updated answer could be string employeeName = chldNode.Attributes["Name"]?.Value;
46

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

3 Comments

A shorthand way of not getting an error for nulls is node.Attributes?["Name"]?.Value
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.
Agreed. Anyone who uses the shorthand way should always make sure it won't cause problems downstream.
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
    }
}

1 Comment

this will be more preferable..:)
7

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".

Comments

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

1 Comment

The methods above didn't work for my XML (though I wish they had). This method does! Thanks!
3

Use

item.Attributes["Name"].Value;

to get the value.

Comments

1

You can also use this;

string employeeName = chldNode.Attributes().ElementAt(0).Name

Comments

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.

Comments

0

Expanding on Konamiman's solution above. I needed to loop through multiple attributes for a node.

Telecom theTelecom = new Telecom();
if (node.HasAttributes)
{
     var nameAttributeList = node.Attributes();
     foreach (XAttribute a in nameAttributeList)
     {
         if ((null != a.Name?.LocalName) && 
               ("use" == a.Name.LocalName))
         {
             theTelecom.use = a.Value;
         }
         if ((null != a.Name?.LocalName) && 
               ("value" == a.Name.LocalName))
         {
             theTelecom.value = a.Value;
         }
     }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.