JohnMunich
JohnMunich

Reputation: 631

c# read attribute value

ich have a xml file with the following structure:

<layer1 name="this is layer1">
  <messages>
    <message name ="com_request">0</message>
    <message name="send">1</message>
    <message name="request">2</message>
  </messages>
</layer1>

I try to collect all the message names in one indexer using the code:

SampleCollection<string> paramCollection = new SampleCollection<string>();

string pathxml = @"C:\myXML.xml";
int j=0;

XmlTextReader xmlin = new XmlTextReader(pathxml);
XmlDocument xmldoc = new XmlDocument();
XmlNode node = xmldoc.ReadNode(xmlin);

foreach (XmlNode item in node.ChildNodes)
{
   paramCollection[j] = item.Attributes["message name"].Value;
   Console.WriteLine(paramCollection[j]);
   j++;
}

However it doesn't work. Please help.

Upvotes: 1

Views: 1760

Answers (7)

Dan Abramov
Dan Abramov

Reputation: 268235

Firstly, as other have pointed out, your attribute is called name.

As for your task to collect some values in XML tree, you could have used XPath language to query the document. This would enable you to avoid writing boilerplate code that traverses the tree, as well as easily adapt to XML structure changes:

var doc = new XmlDocument ();
doc.LoadXml (xs);

var attrs = doc.SelectNodes ("/layer1/messages/message/@name");
var values = attrs.Cast<XmlAttribute> ()
    .Select (a => a.Value);

However, since I already used LINQ to cast nodes into attribute instances, it makes sense to use LINQ to XML instead, which was designed for querying XML from C# code:

var doc = XDocument.Parse (xs);
var values = from msg in doc.Descendants ("message")
             select msg.Attribute ("name").Value;

Console.WriteLine (values);

Both of these options are good and depend on what framework you plan to use for working with XML, System.Xml or LINQ to XML. For new code, I suggest using LINQ.

In both cases, you need a simple foreach loop to enumerate values:

foreach (string value in values)
    Console.WriteLine (value);

Upvotes: 0

Murat Kazanova
Murat Kazanova

Reputation: 349

If you are using Linq to XML

var doc = XDocument.Load(@"d:\temp\myXml.xml");
var msgnames = from q in doc.Descendants("message")
               select q.Attribute("name").Value; 

foreach(string item in msgnames)
{
    Console.WriteLine(item);
}

Upvotes: 0

BrokenGlass
BrokenGlass

Reputation: 160862

In addition to what others have mentioned (attribute name is wrong), also your node points to layers1, who only has the direct child messages, so there are no message nodes in your child collection. The same thing in LINQ is trivial - switch if you can:

XDocument doc = XDocument.Load(@"test.xml");
foreach (var item in doc.Descendants("message"))
{
    Console.WriteLine(item.Attribute("name").Value);
}

Upvotes: 1

Andy
Andy

Reputation: 759

Your node selection is wrong. Its needs to be more like:

string pathxml = @"C:\myXML.xml";
int j=0;

XmlTextReader xmlin = new XmlTextReader(pathxml);
XmlDocument xmldoc = new XmlDocument();
XmlNode node = xmldoc.ReadNode(xmlin);

foreach (XmlNode item in xmldoc.SelectNodes("layer1/messages/message"))
{
    paramCollection[j] = item.Attributes["name"].Value;
    Console.WriteLine(paramCollection[j]);
    j++;
}

So you get a collection of message nodes for the foreach to iterate over. Then the attribute is simple referenced as 'name'

Upvotes: 1

marc_s
marc_s

Reputation: 754408

Try this:

XmlDocument xmldoc = new XmlDocument();

XmlNodeList list = xmldoc.SelectNodes("/layer1/messages/message");
List<string> messageNames = new List<string>();

foreach (XmlNode node in list)
{
   messageNames.Add(node.Attributes["name"].Value);    
}

This should extract all <message> nodes using XPath, and then grab their @name attribute into a list of strings.

Upvotes: 1

Steven Ryssaert
Steven Ryssaert

Reputation: 1967

The attribute name is not message name, it is name

foreach (XmlNode item in node.ChildNodes)
{
   paramCollection[j] = item.Attributes["name"].Value;
   Console.WriteLine(paramCollection[j]);
   j++;
}

Upvotes: 1

Adam Robinson
Adam Robinson

Reputation: 185633

The name of your attribute is name, not message name (message is the name of the node).

If you can describe more clearly what you're trying to do, I (or someone else) can provide a more specific solution.

Upvotes: 3

Related Questions