XPath和属性

3

我正在尝试遍历一个XML文档并选择特定的节点属性。这个XML是动态生成的。

<?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 的默认索引器的文档(和智能感知)中说:“与指定名称匹配的第一个 XmlElement。”属性不是元素。 - Tom W
4个回答

3

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

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

2

要选择最后节点的分辨率属性,您需要使用:

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
最佳实践是在获取值之前检查属性是否不为null。 - Kamil Lach

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

with:

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

这并不是重点,但你可能不会相信这个说法...我刚刚看到了你的回答,可能原因是它只是一个提示,而我告诉OP他需要做什么才能在修改后使代码按预期工作。请复制并粘贴我的答案到你的回答中,我将删除我的答案。 - Dimitre Novatchev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接