更新以前的名单?

时间:2016-05-15 18:37:28

标签: .net vb.net

所以我在后台工作者中创建了一个包含开始和结束时间等的列表来处理电视节目列表我也把电视节目的频道名称放在其中。所以现在我想要处理频道列表,它还有频道名称和频道直播。

如何将其添加到后台工作者中创建的列表中?

代码:

'Guide and Channel Information;
Public Class Channel

    Public Property Channel As String
    Public Property Stream As String
    Public Property Genre As String
    Public Property StartTime As String
    Public Property EndTime As String
    Public Property Programme As String
    Public Property Description As String

    Public Overrides Function ToString() As String
        Return Channel
        Return Stream
        Return Genre
        Return StartTime
        Return EndTime
        Return Programme
        Return Description
    End Function

End Class

'Make a List for the Guide Information;
Public Guide As New List(Of Channel)
Private Sub ProcessGuide_DoWork(sender As Object, e As DoWorkEventArgs) Handles ProcessGuide.DoWork

    Try

        Dim nodelist As XmlNodeList
        Dim node As XmlNode

        'Create the XML Document;
        Dim xmld As XmlDocument
        xmld = New XmlDocument()

        'Load the XMLTV File;
        xmld.Load("http://104.233.125.128/gmtplus0.xmltv")

        'Loop through the Programme Nodes;
        nodelist = xmld.SelectNodes("/tv/programme")
        For Each node In nodelist

            'Here I am adding the Channel etc, But I will also need the stream etc added which is why I have a sub later on in the code to get and add the Stream. But how do I add it to this same Guide List?
            Guide.Add(New Channel() With {
                .Channel = node.Attributes.GetNamedItem("channel").Value,
                .StartTime = node.Attributes.GetNamedItem("start").Value,
                .EndTime = node.Attributes.GetNamedItem("stop").Value,
                .Programme = node.ChildNodes.Item(0).InnerText,
                .Description = node.ChildNodes.Item(1).InnerText
            })

        Next

        ProcessChannels.RunWorkerAsync()

    Catch ex As Exception

        'Error trapping
        Console.Write(ex.ToString(), "TTTTTdsg")

    End Try

End Sub

'Process the Channel Information;
Dim AllChannels As List(Of Channel) = New List(Of Channel)()
Dim EntertainmentChannels As List(Of Channel) = New List(Of Channel)()
Dim KidsChannels As List(Of Channel) = New List(Of Channel)()
Dim SportsChannels As List(Of Channel) = New List(Of Channel)()
Dim DocumentaryChannels As List(Of Channel) = New List(Of Channel)()
Dim NewsChannels As List(Of Channel) = New List(Of Channel)()
Dim MusicChannels As List(Of Channel) = New List(Of Channel)()
Public Sub ProcessChannels_DoWork(sender As Object, e As DoWorkEventArgs) Handles ProcessChannels.DoWork

    'Try to Load the Channel Data;
    Try

        'Connect to the Proxy Source and Prepare the Response;
        Dim source As Net.HttpWebRequest = Net.WebRequest.Create("http://gameshare.io/pragma/channels.php")
        Dim response As Net.HttpWebResponse = source.GetResponse

        'Load the HTML and Convert the JSON to a Readable Array;
        Dim reader As IO.StreamReader = New IO.StreamReader(response.GetResponseStream())
        Dim html As String = reader.ReadToEnd
        Dim json = JsonConvert.DeserializeObject(html)

        '=========================================================
        '=========================================================
        'Here is where I need to not add the Guide info to a NEW Channel/Guide/List I need to add it to the same one
        'that is made in ProcessGuide_DoWork but how?

        'Process All Channels;
        For i As Integer = 0 To json("Quantity").ToString - 1
            For Each Row In json("All Channels")
                AllChannels.Add(New Channel() With {
                    .Channel = Row(i)("title").ToString,
                    .Stream = Row(i)("stream").ToString
                })
            Next
        Next

        'Process Enterainment Channels
        For i As Integer = 0 To json("EQuantity").ToString - 1
            For Each Row In json("Entertainment")
                EntertainmentChannels.Add(New Channel() With {
                    .Channel = Row(i)("title").ToString,
                    .Stream = Row(i)("stream").ToString
                })
            Next
        Next

        'Process Kids Channels;
        For i As Integer = 0 To json("KQuantity").ToString - 1
            For Each Row In json("Kids")
                KidsChannels.Add(New Channel() With {
                    .Channel = Row(i)("title").ToString,
                    .Stream = Row(i)("stream").ToString
                })
            Next
        Next

        'Process Sports Channels;
        For i As Integer = 0 To json("SQuantity").ToString - 1
            For Each Row In json("Sports")
                SportsChannels.Add(New Channel() With {
                    .Channel = Row(i)("title").ToString,
                    .Stream = Row(i)("stream").ToString
                })
            Next
        Next

        'Process Documentary Channels;
        For i As Integer = 0 To json("DQuantity").ToString - 1
            For Each Row In json("Documentary")
                DocumentaryChannels.Add(New Channel() With {
                    .Channel = Row(i)("title").ToString,
                    .Stream = Row(i)("stream").ToString
                })
            Next
        Next

        'Process News Channels;
        For i As Integer = 0 To json("NQuantity").ToString - 1
            For Each Row In json("News")
                NewsChannels.Add(New Channel() With {
                    .Channel = Row(i)("title").ToString,
                    .Stream = Row(i)("stream").ToString
                })
            Next
        Next

        'Process Music Channels;
        For i As Integer = 0 To json("MQuantity").ToString - 1
            For Each Row In json("Music")
                MusicChannels.Add(New Channel() With {
                    .Channel = Row(i)("title").ToString,
                    .Stream = Row(i)("stream").ToString
                })
            Next
        Next

        'Add all the Channels to the Channels ComboBox;
        ChannelsBox.Items.AddRange(allchannels.ToArray)

        'The Channels are now ready to be used, Tell the user to Select a Channel;
        ChannelsBox.Text = "Select a Channel..."

    Catch ex As Exception

        'Channel Data couldn't be loaded;
        ErrorImage.Width = "640"
        ErrorImage.Height = "391"
        ErrorImage.Visible = True

    End Try

End Sub

1 个答案:

答案 0 :(得分:1)

您的代码需要进行重大修改。首先,你应该开启Option Strict;像这样的代码将无法编译,因为它使用后期绑定:

For Each Row In json("All Channels")

从根本上说,解析XML后,每个频道的列表中都有一个条目。然后你不能迭代json电视节目列表并将它们插入该列表:每个频道都有许多电视节目。您没有数组或列表来存储每个频道的多个节目。

也不需要BackGroundWorker。如果您反序列化为类型化对象,JSON.NET将为您创建所有这些列表,而不是通过Object循环并手动创建这些列表。

因此,您需要一个类将URL链接到频道(TVGChannel),并且需要一个类来包含电视广播的数据。节目列表/指南的一个属性是它是一个频道。 XML数据包含每个节目的Category,它似乎比频道类别更有趣。

希望,XML中的channel元素确实用于指定json中由title指示的通道,并且它们不是数据的意外比赛。它看起来更像是应该在同一个XML中引用通道部分中的某些东西,但那些只有URL。

计划类

Public Enum ProgrammeGenre
    Entertainment
    Kids
    Sports
    Documentary
    News
    Music
    Other
End Enum

Public Class Programme
    Public Property Name As String
    Public Property Title As String                 ' episode Title
    Public Property Description As String

    Public Property Channel As TVGChannel

    Public Property Genre As ProgrammeGenre

    Public Property StartTime As DateTime
    Public Property EndTime As DateTime

    Public Property Category As String
    Public Property EpisodeId As String
    Public Property Stars As Decimal

    Public Sub New()
        Genre = ProgrammeGenre.Other
    End Sub
 End Class

正如您所看到的,我将其扩展为其他一些元素并更改了一些类型,最明显的是DateTime的开始和结束时间。 Category属性存储XML中的类别,而Genre是它所在列表的结果:

thisPrgURL = myProgrammes(n).Channel.stream

TVGContainer,TVGChannel

Public Class TVGChannel
    Public Property stream As String
    Public Property title As String

    Public Overrides Function ToString() As String
        Return title
    End Function
End Class

Public Class TVGContainer
    'Public Property Quantity As String
    '...
    <JsonProperty("All Channels")>
       Private Property _AllChannels As TVGChannel()()

    ' none of these are really very useful:
    Public Property Entertainment As TVGChannel()()
    Public Property Kids As TVGChannel()()
    Public Property Sports As TVGChannel()()
    Public Property Documentary As TVGChannel()()
    Public Property News As TVGChannel()()
    Public Property Music As TVGChannel()()

    Friend ReadOnly Property AllChannels As TVGChannel()
        Get
            Return _AllChannels(0)
        End Get
    End Property
End Class

这些?Quantity属性都没有多大价值,而频道列表子集的唯一作用是Programme上的Genre属性 - 它们都可以被注释掉。我不知道为什么他们把它们作为锯齿状阵列提供;我不想处理它,因此JSON在反序列化时会进入_AllChannels,但代码将使用AllChannels属性。

表单级别变量

Private myPrograms As List(Of Programme)
Private ChannelGuide As TVGContainer

解析指南

您需要在处理XML之前构建指南,以便可以为每个节目分配频道:

Private Sub ParseGuide()

    Dim jstr = from whereever
    ChannelGuide = JsonConvert.DeserializeObject(Of TVGContainer)(jstr)

End Sub

通过对一个类型化对象进行deserialing,不需要逐个解析所有这些东西,它应该更快(更快); ChannelGuide将包含所有这些数组。

创建程序列表(XML)

我对XML的处理方式进行了重大更改。大多数都是为了提高速度,减少维护或更可靠的处理:

Private Sub ParseXMLTV()
    Dim nodelist As XmlNodeList
    Dim node As XmlNode

    Dim xmld As New XmlDocument()
    xmld.Load("http://104.233.125.128/gmtplus0.xmltv")

    myPrograms = New List(Of Programme)
    nodelist = xmld.SelectNodes("/tv/programme")
    Dim p As Programme

    For Each node In nodelist
        p = New Programme()

        Dim dt = DateTimeOffset.ParseExact(node.Attributes.GetNamedItem("start").Value,
                           "yyyyMMddHHmmss KKKK", CultureInfo.InvariantCulture).DateTime
        p.StartTime = dt
        dt = DateTimeOffset.ParseExact(node.Attributes.GetNamedItem("stop").Value,
                           "yyyyMMddHHmmss KKKK", CultureInfo.InvariantCulture).DateTime
        p.EndTime = dt

        ' now, find the channel indicated
        Dim ch = node.Attributes.GetNamedItem("channel").Value
        If String.IsNullOrEmpty(ch) = False Then
            Dim tvgc = ChannelGuide.AllChannels.FirstOrDefault(Function(q) q.title = ch)
            If tvgc IsNot Nothing Then
                p.Channel = tvgc
            Else
                ' ToDo: add an UNKNOWN channel to avoid NRE
            End If
        End If

        p.Genre = GetGenre(ch)

        For Each n As XmlNode In node.ChildNodes
            Select Case n.Name
                Case "title"
                    p.Name = n.InnerText
                Case "sub-title"
                    p.Title = n.InnerText
                Case "desc"
                    p.Description = n.InnerText
                Case "star-rating"
                    p.Stars = Convert.ToDecimal(n.InnerText.Split(" "c)(0))
                Case "episode-num"
                    p.EpisodeId = n.InnerText
                Case "category"
                    p.Category = n.InnerText
            End Select
        Next

        myPrograms.Add(p)

    Next
End Sub

Private Function GetGenre(ch As String) As ProgrammeGenre
    ' this is not needed - the XML provides a show category
    ' "Drama" or "SitCom" is more interesting than `Entertainment`

    If ChannelGuide.Documentary(0).
                FirstOrDefault(Function(f) f.title = ch) IsNot Nothing Then
        Return ProgrammeGenre.Documentary
    ElseIf ChannelGuide.Entertainment(0).
                FirstOrDefault(Function(f) f.title = ch) IsNot Nothing Then
        Return ProgrammeGenre.Entertainment
    ElseIf ... 
        ' repeat for others
    Else
        Return ProgrammeGenre.Other
    End If
End Function

用法

ParseGuide()
If ChannelGuide IsNot Nothing AndAlso ChannelGuide.AllChannels.Count > 0 Then
    ParseXMLTV()
End If
dgvTV.DataSource = myPrograms

整个过程需要6秒才能运行(包括下载时间和发布到DGV),因此BackGroundWorker没有真正的理由。如果没有根据频道类别钓掉 show 类型的话,它会更快......而且还有很多都缺失了。

enter image description here

EndTimeCategory,剧集ID和星级都向右滚动。

DateTime解析可能需要解决,但我不知道在哪里可以找到此API的文档。