tags:

views:

173

answers:

5

Suppose I have the following XML Document.

<reply success="true">More nodes go here</reply>

How to get the value of the attribute success, which in this case would be the string "true".

+3  A: 

I would try something like this:

XmlDocument doc = new XmlDocument();
doc.LoadXml("<reply success=\"true\">More nodes go here</reply>");

XmlElement root = doc.DocumentElement;

string s = root.Attributes["succes"].Value;
Rewinder
You could also try to get the attribute by name: root.Attributes["succes"].Value
Rewinder
It's generally very bad practice to access attributes by position, because by definition the ordering of attributes on XML elements is not significant. In this trivial case it works because there's only one attribute, but that's just being lucky.
Robert Rossney
You're right, I already suggested the alternative in my first comment. I now have edited my original post to show it.
Rewinder
A: 

Here's an alternative solution using XmlReader which may be a little more efficient than using XmlDoument although that's proably negligible on such a small XML document

string input = "<reply success=\"true\">More nodes go here</reply>";

using (XmlReader xmlReader = XmlReader.Create(new StringReader(input)))
{
    xmlReader.MoveToContent();
    string success = xmlReader.GetAttribute("success");
    Console.WriteLine(success);
}
Daniel Renshaw
Wow, three answers in a row that all do the same wrong thing three different ways.
Robert Rossney
I think the general impression the original question gave was that we are supposed to find the value for the first attribute. I have now corrected my code to do the more generally useful thing that you suggested.
mumtaz
@Robert: fair enough, answer changed
Daniel Renshaw
+1  A: 
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;



    class MyClass
    {

        static void Main(string[] args)
        {

            XElement xmlcode =
            XElement.Parse("<reply success=\"true\">More nodes go  </reply>");

            var successAttributes =
                                    from attribute in xmlcode.Attributes()
                                    where attribute.Name.LocalName=="success" 
                                    select attribute ;




            if(successAttributes.Count()>0)
            foreach (var sa in successAttributes)
            {

                Console.WriteLine(sa.Value);



            }



            Console.ReadLine();





        }



    }
mumtaz
See my comment on Rewinder's answer; this answer has exactly the same problem. It will work in this trivial case, but is a very bad practice in general.
Robert Rossney
Yeah, you are right. I edited the code to make it look for and print the value of all the 'success' attribute values in the XML snippet regardless of their order or location. Now give my Zero back :)
mumtaz
+1  A: 

If you load the XML into an XmlDocument, there are any number of ways to get the attribute's value. You could use XPath to find the attribute:

XmlAttribute a = doc.SelectSingleNode("/reply/@success");
Console.Write(a.Value);

If you already have the XmlElement that the attribute appears on (which in this case is the document element), then you can just use GetAttribute:

Console.Write(doc.DocumentElement.GetAttribute("success"));

There are similar approaches if you're using XPathDocument or XmlReader or XDocument.

In all cases, though, you want to be getting the attribute by its name, not its position. In your test case there's only one attribute; in any real-world application multiple attributes are likely, and attribute ordering in XML is not significant. These two elements are semantically equivalent:

<a foo='true' bar='false'/>

<a bar='false' foo='true'/>

You don't even know that the XML parser will present attributes to you in the same order they appear in the document; depending on the implementation, the parser may give them to you in alphabetical order, or in random order. (I've seen both.)

Robert Rossney
But we are talking C#/.NET specifically here and there's no mention in the MS documentation that either `XmlReader` or `XmlDocument` indexes attributes in anything other than document/input order so if the requirement was to "get the first attribute that appears in the input XML", this can be achieved by looking for the attribute with index zero. Of course, the question isn't asking for the "first" attribute so it is correct in this case to use attribute name instead of index.
Daniel Renshaw
There's no guarantee in the MS documentation that `XmlDocument` (actually, `XmlNamedNodeMap`) indexes attributes in any deterministic order. There are examples showing that nodes are indexed in the order they're added to the map. But those examples are on this page - http://msdn.microsoft.com/en-us/library/7sf9z378.aspx - and what, pray, is the very first word in the title?
Robert Rossney
A: 
var at = 
XElement.Parse("<reply success=\"true\">More nodes go  </reply>").Attribute("success");
if (at != null) Console.Write(at.Value);
ASergan