Путь к атрибуту XML с использованием LINQ, генерирующего исключение NullReferenceException - PullRequest
0 голосов
/ 02 марта 2011

Я использую LINQ to XML

Мне не терпится выяснить, почему я получаю исключение NullReferenceException в части MyUrl из выбора LINQ ниже. Чего мне не хватает?

    XElement xmlRssItems = XElement.Parse(e.Result);
                podlist.ItemsSource = from rssItem in xmlRssItems.Element("channel").Elements("item")
                        where rssItem.Element("enclosure") != null
                        select new PodcastItem
                         {
                             Title = (string)rssItem.Element("title"),
                             MyUrl = new Uri(rssItem.Element("enclosure").Attribute("url").Value)
                         };

...

public class PodcastItem
    {
        public string Title { get; set; }
        public Uri MyUrl { get; set; }
    }

XML:

<rss>
    <channel>
        <item>
            <guid isPermaLink="false">tag:blogger.com,1999:blog-811823720557864449.post-3786706865099847612</guid>
            <pubDate>Sun, 20 Feb 2011 02:08:00 +0000</pubDate>
             <title>#43 - StarCast: "Mork's Homecoming!"</title>
            <link>http://starcastshow.blogspot.com/2011/02/43-starcast-morks-homecoming.html</link>
            <author>starcastshow@gmail.com (Garrett Weinzierl &amp; Kyle Fergusson)</author>
            <thr:total>1</thr:total>
            <enclosure url="http://feedproxy.google.com/~r/starcast_rss/~5/Xf0YXRRMrPU/episode_43.mp3" length="0" type="audio/mpeg" />
            <feedburner:origEnclosureLink>http://thestarcast.com/shows/starcast/episode_43.mp3</feedburner:origEnclosureLink>
        </item>

ВЫПУСК: * ПРОБЛЕМА БЫЛА, ЧТО В RSS-ФИДЕ БЫЛО ОДИН УСТРОЙСТВО, КОТОРОЕ НЕ ИМЕЕТ ПУНКТ ЗАКРЫТИЯ. Я добавил простую проверку на NULL, и она работает идеально. СПАСИБО ЗА ПРОВЕРКУ САНИТИ. *

1 Ответ

2 голосов
/ 02 марта 2011

Вы редактировали свой тэг rss, чтобы удалить пространства имен? Это прекрасно работает для меня, обратите внимание на «xmlns: thr» и «xmlns: feedburner» в элементе rss:

private void buttonTest1_Click(object sender, RoutedEventArgs e)
{
    string sResult = @"<rss xmlns:thr=""http://www.itunes.com/dtds/random.dtd"" xmlns:feedburner=""http://rssnamespace.org/feedburner/ext/1.0"">
        <channel>
        <item>
            <guid isPermaLink=""false"">tag:blogger.com,1999:blog-811823720557864449.post-3786706865099847612</guid>
            <pubDate>Sun, 20 Feb 2011 02:08:00 +0000</pubDate>
                <title>#43 - StarCast: ""Mork's Homecoming!""</title>
            <link>http://starcastshow.blogspot.com/2011/02/43-starcast-morks-homecoming.html</link>
            <author>starcastshow@gmail.com (Garrett Weinzierl &amp; Kyle Fergusson)</author>
            <thr:total>1</thr:total>
            <enclosure url=""http://feedproxy.google.com/~r/starcast_rss/~5/Xf0YXRRMrPU/episode_43.mp3"" length=""0"" type=""audio/mpeg"" />
            <feedburner:origEnclosureLink>http://thestarcast.com/shows/starcast/episode_43.mp3</feedburner:origEnclosureLink>
        </item>
        </channel>
        </rss>";
    XElement xmlRssItems = XElement.Parse(sResult);
    var result = from rssItem in xmlRssItems.Element("channel").Elements("item")
                            select new PodcastItem
                            {
                                Title = (string)rssItem.Element("title"),
                                MyUrl = new Uri(rssItem.Element("enclosure").Attribute("url").Value)
                            };
    Console.WriteLine("{0}", result);
}

Другой способ справиться с этим - добавить пространства имен и использовать XmlReader для загрузки вашего элемента:

XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable());
xnm.AddNamespace("thr", "");
xnm.AddNamespace("feedburner", "");
XmlParserContext xpc = new XmlParserContext(null, xnm, null, XmlSpace.None);
XmlTextReader xtr = new XmlTextReader(sResult, XmlNodeType.Element, xpc);
XElement xmlRssItems = XElement.Load(xtr);
var result = from rssItem in xmlRssItems.Element("channel").Elements("item")
    select new PodcastItem
    {
        Title = (string)rssItem.Element("title"),
        MyUrl = new Uri(rssItem.Element("enclosure").Attribute("url").Value),
        Total = (string)rssItem.Element("total"),
        OriginalEnclosureLink = (string)rssItem.Element("origEnclosureLink")
    };
Console.WriteLine("{0}", result);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...