2012-02-19 125 views
3

我想遍历一个XML文档并选择某些节点属性。 XML是动态生成的。XPath和属性

<?xml version="1.0" encoding="ISO-8859-1"?> 
<streams> 
<stream> 
<title>+23 (Panama)</title> 
<info resolution="768x420" bitrate="1000kbps"/> ----- Need These 
<swfUrl>http://www.freeetv.com/script/mediaplayer/player.swf</swfUrl> 
<link>rtmp://200.75.216.156/live/</link> 
<pageUrl>http://www.freeetv.com/</pageUrl> 
<playpath>livestream</playpath> 
<language>Music</language> 
<advanced></advanced> 
</stream> 
</streams> 

,我试图用零运气和Visual Studio说用“不,你错了。尝试600多次”的代码是

xDoc.Load("http://127.0.0.1/www/xml.php"); 

       XmlNodeList nodes = xDoc.SelectNodes("/streams/stream"); 
       foreach (XmlNode xn in nodes) 
       { 
        ListViewItem lvi = listView1.Items.Add(xn["title"].InnerText); 
        lvi.SubItems.Add(xn["swfUrl"].InnerText); 
        lvi.SubItems.Add(xn["link"].InnerText); 
        lvi.SubItems.Add(xn["pageUrl"].InnerText); 
        lvi.SubItems.Add(xn["playpath"].InnerText); 
        lvi.SubItems.Add(xn["language"].InnerText); 
        lvi.SubItems.Add(xn["advanced"].InnerText); 
        lvi.SubItems.Add(xn["//info/@resolution"].Value); 
       } 

请告诉我哦智者什么我做错了吗?

+1

魔鬼在细节。默认的“XmlNode”索引器的docs(和Intellisense)表示“第一个匹配指定名称的** XmlElement **”。属性不是元素。 – 2012-02-19 09:17:17

回答

3

如果你想使用XPath选择节点的属性,你应该使用SelectSingleNode方法,如:

xn.SelectSingleNode("info/@resolution").Value 
2

要选择你的最后一个节点的resolution属性,你需要使用:

xn["info"].Attributes["resolution"].Value 

或者,你可以尝试的LINQ to XML为相同的结果(我发现它的API更容易使用):

var doc = XDocument.Parse("http://127.0.0.1/www/xml.php"); 

foreach (var d in doc.Descendants("stream")) 
{ 
    ListViewItem lvi = listView1.Items.Add(d.Element("title").Value); 
    lvi.SubItems.Add(d.Element("swfUrl").Value); 
    // ... 
    vi.SubItems.Add(d.Element("info").Attribute("resolution").Value); 
} 
+2

好的做法是在获取Value之前检查属性!= null。 – 2012-02-19 08:42:10

1

这是一个LINQ to XML的例子,用于从特定属性名称或属性名称列表的整个文档中提取属性。

var xml = XElement.Parse("http://127.0.0.1/www/xml.php"); 

// find all attributes of a given name 
var attributes = xml 
    .Descendants() 
    .Attributes("AttributeName") 

// find all attributes of multiple names 
var attributes = xml 
    .Descendants() 
    .Attributes() 
    .Where(a => ListOfAttribNames.Contains(a.Name.LocalName)) 
0

替换

lvi.SubItems.Add(xn["//info/@resolution"].Value); 

lvi.SubItems.Add(xn.SelectSingleNode("info/@resolution").Value); 
+0

相同的答案已经存在。它是否复制粘贴? – 2012-02-19 19:22:04

+0

这不是,但你可能不相信这个声明......我看到你的答案只是*现在*,可能原因是它只是一个提示,而我告诉OP他需要做什么,以便在执行完成后他的代码的修改将按预期工作。请复制并粘贴*我的*答案到你的,我会删除我的答案。 – 2012-02-19 19:29:11