2012-02-19 3 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

Дьявол кроется в деталях. Документы (и Intellisense) для индексатора по умолчанию «XmlNode» говорят _ «Первый ** XmlElement **, который соответствует указанному имени.» _. Атрибуты не являются элементами. –

ответ

3

Если вы хотите, чтобы выбрать атрибут узла с помощью XPath вы должны использовать SelectSingleNode метод, например:

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

Чтобы выбрать resolution атрибут вашего последнего узла, который нужно использовать:

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

В качестве альтернативы, вы можете попробовать LINQ к 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 до получения значения. –

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

Тот же ответ уже существует. Это копия-вставка? –

+0

Это не так, но вы не можете поверить в это утверждение ... Я вижу ваш ответ просто * сейчас *, и, вероятно, причина в том, что это всего лишь намек, тогда как я говорю OP, что ему нужно сделать, чтобы после выполнения модификация его кода будет работать по назначению. Скопируйте и вставьте * мой * ответ на свой вопрос, и я удалю свой ответ. –