2011-02-28 74 views
1

ICH具有以下结构的XML文件:C#读取属性值

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

我尝试使用代码来收集所有的消息名称在一个索引:

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++; 
} 

但是它不”工作。请帮忙。

+1

你能更具体与错误? – Paolo 2011-02-28 14:21:32

回答

1

除了什么其他人所说的(属性名称是错误的),也是你的节点指向layers1,谁只有直接子messages,所以在没有message节点你的孩子收藏。在LINQ同样的事情是微不足道的 - 开关,如果你可以:

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

虽然我使用system.xml.linq.xdocument添加,但是xdocument用红色标注加下划线。 – JohnMunich 2011-02-28 15:35:07

+0

@JohnMunich:你应该只需要'使用System.Xml.Linq;'这个工作 – BrokenGlass 2011-02-28 15:49:58

+0

非常感谢!有用。 – JohnMunich 2011-02-28 15:54:49

3

属性的名称是name,而不是message namemessage是节点的名称)。

如果你能更清楚地描述你想要做什么,我(或其他人)可以提供更具体的解决方案。

1

属性名称是message name,它是name

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

试试这个:

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

这应该使用XPath提取所有<message>节点,然后抓住他们@name属性转换为字符串列表。

+0

你能给我任何关于xpath的例子吗? – JohnMunich 2011-02-28 15:31:17

+0

@JohnMunich:'/ layer1/messages/message'是一个XPath表达式... – 2011-02-28 16:05:11

1

您的节点选择错误。它的需求更像:

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++; 
} 

所以你得到一个foreach迭代的消息节点的集合。然后属性简单引用为“名”

+0

其奇怪,它仍然不起作用。由于评论:'<?xml version =“1.0”encoding =“utf-8”standalone =“yes”?> ' – JohnMunich 2011-02-28 15:28:34

+0

我可以看到整个文件的示例吗? – Andy 2011-02-28 15:45:57

+0

我刚刚发现了我的代码调整问题。将xmldoc.SelectNodes(“layer1/messages/message”)更改为node.SelectNodes(“messages/message”) – Andy 2011-02-28 15:51:28

0

如果您正在使用LINQ到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); 
} 
0

首先,正如其他人指出,你的属性称为name

至于您的任务是收集XML树中的某些值,您可以使用XPath语言来查询文档。这将使你避免编写遍历树样板代码,以及很容易适应XML结构的变化

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

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

但是,因为我已经使用LINQ投节点为属性的情况下,它使感觉使用LINQ到XML代替,这是专为从C#代码查询XML:

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

Console.WriteLine (values); 

这两个选项是好的,取决于你打算使用与XML,的System.Xml或工作什么框架LINQ to XML。对于新代码,我建议使用LINQ。

在这两种情况下,你需要一个简单的foreach循环枚举值:

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

如何检索值中的值? – JohnMunich 2011-02-28 15:39:30

+0

对不起,我不明白你的意思。在两种情况下,'values'的类型都是'IEnumerable ',这意味着你可以在'foreach'循环中通过它们:'foreach(值为字符串值)'。如果您需要'List '或'string []'数组,请在'values'处调用'ToList'或'ToArray'。 – 2011-02-28 15:56:57