Member 12111727 Ответов: 0

Проверьте, есть ли у XML определенный узел


Я строю трекер стихийных бедствий, используя RSS-канал от различных агентств. Большинство структур RSS-каналов одинаковы, но у меня есть один канал из НАСА, который немного отличается от остальных. У других есть узел изображения для URL-адреса логотипа агентства поставщика каналов, который отлично работает, но у NASA нет узла ImageURL для их логотипа. Я использую одну функцию, чтобы в основном извлекать RSS-данные и заполнять ими DataGridView и элементы формы(метки и pictureboxes). Я бросил код, который ищет узел url-адреса изображения в TRY/CATCH, но он все равно выдает ошибку, потому что не может найти узел imageURL.

Моя функция для извлечения и заполнения данных
<pre>Public Function SelectFeedToDisplay(FeedList As ComboBox, DataGrid As DataGridView, ProviderName As Label, ProviderImage As PictureBox, ProviderDesc As Label, ProviderLink As LinkLabel, FeedBuildDate As Label, ArticleLink As LinkLabel, ArticleTitle As Label, ArticleDate As Label, ArticleText As Label)
        'RSS Connect
        Dim url As String = FeedList.SelectedItem
        Dim rssFeed As HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
        Dim response = rssFeed.GetResponse()
        Dim rssStream = response.GetResponseStream()
        Dim rssDoc As New XmlDocument()
        rssDoc.Load(rssStream)

        'Feed Provdier Basics
        Dim feedImage As XmlNode = rssDoc.SelectSingleNode("rss/channel/image")
        Dim feedTitle As XmlNode = rssDoc.SelectSingleNode("rss/channel/title")
        Dim feedDesc As XmlNode = rssDoc.SelectSingleNode("rss/channel/description")
        Dim feedLink As XmlNode = rssDoc.SelectSingleNode("rss/channel/link")
        Dim lastBuildDate As XmlNode = rssDoc.SelectSingleNode("rss/channel/lastBuildDate")

        'Feed Items
        Dim rssItems As XmlNodeList = rssDoc.SelectNodes("rss/channel/item")
        Dim i As Integer = 0
        Dim dt As DataTable = New DataTable("table")
        dt.Columns.Add("Title", Type.GetType("System.String"))
        dt.Columns.Add("Date", Type.GetType("System.String"))
        dt.Columns.Add("Text", Type.GetType("System.String"))
        dt.Columns.Add("Link", Type.GetType("System.String"))

        'Express Item Data
        While i < rssItems.Count
            Try
                Dim node As XmlNode = rssItems.Item(i).SelectSingleNode("title")
                If feedImage.SelectSingleNode("url") IsNot Nothing Then
                    Dim feedPic As XmlNode = feedImage.SelectSingleNode("url")
                    If feedPic IsNot Nothing Then
                        Dim imageURL As String = feedPic.InnerText
                        ProviderImage.Load(imageURL)
                    Else
                        feedImage = Nothing
                    End If
                End If
                Dim title As String
                Dim link As String
                Dim pubDate As String
                Dim desc As String
                'Feed Provider
                If feedTitle IsNot Nothing Then
                    ProviderName.Text = feedTitle.InnerText

                Else
                    ProviderName.Text = Nothing
                End If

                If lastBuildDate IsNot Nothing Then
                    FeedBuildDate.Text = lastBuildDate.InnerText

                Else
                    FeedBuildDate.Text = Nothing
                End If

                If feedDesc IsNot Nothing Then
                    ProviderDesc.Text = feedDesc.InnerText

                Else
                    ProviderDesc.Text = Nothing
                End If



                If feedLink IsNot Nothing Then
                    ProviderLink.Tag = feedLink.InnerText

                Else
                    ProviderLink.Tag = Nothing
                End If

                'Item Nodes
                If node IsNot Nothing Then
                    title = node.InnerText

                Else
                    title = ""
                End If

                node = rssItems.Item(i).SelectSingleNode("pubDate")
                If node IsNot Nothing Then
                    pubDate = node.InnerText
                Else
                    pubDate = ""
                End If

                node = rssItems.Item(i).SelectSingleNode("link")
                If node IsNot Nothing Then
                    link = node.InnerText

                Else
                    link = Nothing
                End If

                node = rssItems.Item(i).SelectSingleNode("description")
                If node IsNot Nothing Then
                    desc = node.InnerText
                Else
                    desc = ""
                End If
                Dim dr As DataRow = dt.NewRow()
                dr("Title") = title
                dr("Date") = pubDate
                dr("Text") = desc
                dr("Link") = link
                dt.Rows.Add(dr)
                i += 1
            Catch ex As Exception

            End Try

        End While
        DataGrid.DataSource = dt
        Return Nothing

    End Function


Проблема заключается в операторе IF внутри оператора TRY:
If feedImage.SelectSingleNode("url") IsNot Nothing Then
                    Dim feedPic As XmlNode = feedImage.SelectSingleNode("url")
                    If feedPic IsNot Nothing Then
                        Dim imageURL As String = feedPic.InnerText
                        ProviderImage.Load(imageURL)
                    Else
                        feedImage = Nothing
                    End If
                End If




Каков был бы наилучший и эффективный способ проверить, существует ли определенный узел, прежде чем пытаться извлечь из него информацию? Я хотел бы реализовать его для всех узлов, так как пользователь приложения сможет загружать свои собственные RSS-каналы, и если они будут отличаться от предоставленных, у меня есть ощущение, что будут проблемы похуже, чем это.

Что я уже пробовал:

попробуйте уловить утверждения
Если это не утверждения
Гугл

Richard MacCutchan

Если вы не можете найти узел, то создайте фиктивную ссылку, чтобы остальная часть вашего кода не зависала.

0x01AA

Вы можете это подтвердить feedImage сам по себе действителен?

Member 12111727

Да, feedImage действителен. Ошибка, которую я получаю, такова

System.NullReferenceException: 'Object reference not set to an instance of an object.'


а код, который выдает ошибку, таков:
If feedImage.SelectSingleNode("url") IsNot Nothing Then

0x01AA

Но для меня это означает именно это feedImage является нулевым.
Я бы также проверил здесь с
If feedImage IsNot Nothing Then

Richard MacCutchan

Это происходит потому, что вы не проверяете свои результаты, когда пытаетесь получить узел из XML. Вы никогда не должны предполагать, что результат вызова метода вернет то, что вы ожидаете.

Maciej Los

Можете ли вы предоставить xml-данные?

0 Ответов