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.
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.
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);
}
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++;
}
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.
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'
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);
}
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);
精彩评论