所以我在后台工作者中创建了一个包含开始和结束时间等的列表来处理电视节目列表我也把电视节目的频道名称放在其中。所以现在我想要处理频道列表,它还有频道名称和频道直播。
如何将其添加到后台工作者中创建的列表中?
代码:
'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
答案 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
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的处理方式进行了重大更改。大多数都是为了提高速度,减少维护或更可靠的处理:
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 类型的话,它会更快......而且还有很多都缺失了。
EndTime
,Category
,剧集ID和星级都向右滚动。
DateTime
解析可能需要解决,但我不知道在哪里可以找到此API的文档。