Roku Developer Program

Join our online forum to talk to Roku developers and fellow channel creators. Ask questions, share tips with the community, and find helpful resources.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
jbrave
Channel Surfer

XML validity testing again

I have a function that blows up on the last element in a for each loop. I tried to figure out how to implement TheEndless suggestion:

xmlcheck=m.xmlTrackList.track.GetNamedElements("stream-url")
if xmlcheck <> invalid and xmlcheck.count() >0

but the problem is, the result is zero so this fails, but the most of the records seem to be good, so I think I'm not checking the correct thing.

What I"m doing is requesting 20 records from the server and getting back 19. For some reason the 19th record crashes me to the debugger with:runtime error ec: 'Dot' Operator attempted with invalid BrightScript Component or interface reference.

180: xmlcheck=m.xmlTrackList.track.GetNamedElements("stream-url").[counter].GetText()

The idea of the above line was to try to validate the xml before calling the sub that actually does the assignment & posteritems so that I could leave

Any ideas would be helpful. I want to check each time through the for each loop if the data is good. If the problem is that there aren't 19 records then wouldn't the For Each only cycle the number of track in xmltracklist.track?

hope i'm making sense.

- Joel
Screenshades: The first Screensaver for Roku2!
Musiclouds: The best free internet music, on your Roku!
Ouroborialis: Psychedelic Screensaver for Roku!
0 Kudos
18 REPLIES 18
TheEndless
Channel Surfer

Re: XML validity testing again

What is ".[counter]" in that line? That syntax seems odd...
Can you provide the code for the full loop?
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
jbrave
Channel Surfer

Re: XML validity testing again

counter is an integer that increments at the end of each loop.

print "ok well that didn't blow up so now do that parsing stuff"
if m.xmlTracklist.Parse(m.xferResult)
print "parse is true"
counter=0
print "counter="+counter.ToStr()
For Each track in m.xmlTrackList.track
?"************xmlcheck***************"
xmlcheck=m.xmlTrackList.track.GetNamedElements("stream-url").[counter].GetText()
?"***********************************"
if xmlcheck <> invalid and xmlcheck <> "" then 'doesn't ever get this far on the last iteration because xmlcheck crashes
?"xml check success"
GetTrackSet(counter, track) ' this function is where it would die
print m.TrackTitle+", "+m.TrackURL
posterlist.push(CreatePosterItems())
counter=counter+1
print "counter="+counter.ToStr()
else
?"xmlcheck failed"
end if
Next
End If
return posterlist
end function

function getTrackSet(counter as integer, track as object) as object
....
m.TrackURL = m.xmlTrackList.track.GetNamedElements("stream-url").[counter].GetText()+m.ckey 'this line would blow up if it didn't blow up in the calling function
....

end function



Screenshades: The first Screensaver for Roku2!
Musiclouds: The best free internet music, on your Roku!
Ouroborialis: Psychedelic Screensaver for Roku!
0 Kudos
TheEndless
Channel Surfer

Re: XML validity testing again

I really don't understand that [counter] part. And your outer look doesn't makes sense either, since you're not using "track". Try this instead...

If m.xmlTracklist.Parse(m.xferResult) Then
print "parse is true"
counter=0
print "counter="+counter.ToStr()
For Each track in m.xmlTrackList.track
xmlStreamUrls = track.GetNamedElements("stream-url")
If xmlstreamUrl <> invalid And xmlStreamUrls.Count() > 0 Then
xmlcheck = xmlStreamUrls[ 0 ].GetText()
if xmlcheck <> invalid and xmlcheck <> "" then 'doesn't ever get this far on the last iteration because xmlcheck crashes
?"xml check success"
GetTrackSet(counter, track) ' this function is where it would die
print m.TrackTitle+", "+m.TrackURL
posterlist.push(CreatePosterItems())
counter=counter+1
print "counter="+counter.ToStr()
else
?"xmlcheck failed"
end if
End If
Next
End If
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
TheEndless
Channel Surfer

Re: XML validity testing again

Also, why aren't you passing the stream url to the getTrackSet function? Your code is inefficiently grabbing an roXMLList every time you call to those xml nodes, which isn't necessary, since you looping through them to begin with. It seems to me, the [counter] part you have in there now is only working by chance. It could easily get out of sync if any one of the elements didn't have a "stream-url" node.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
jbrave
Channel Surfer

Re: XML validity testing again

"TheEndless" wrote:
Also, why aren't you passing the stream url to the getTrackSet function? Your code is inefficiently grabbing an roXMLList every time you call to those xml nodes, which isn't necessary, since you looping through them to begin with. It seems to me, the [counter] part you have in there now is only working by chance. It could easily get out of sync if any one of the elements didn't have a "stream-url" node.


the stream url is in m.url which is accessable from anywhere, but the GetTrackSet function is where the streamurl is actually extracted from the xml which is acquired a few lines above what I pasted in - it is fully of print statements and rather hard to read, but here is the complete function as it stands now unmodified:

'***********************************************
'get searched for tracks
'***********************************************

function getsearchTracks(ofs as integer, lim as integer, querystring as string) as object
posterlist=createobject("roarray",1,true)
m.audioplayer.clearcontent()
print "searchtracks="+querystring
offset=ofs.tostr()
print "offset="+offset
limit=lim.tostr()
print "limit="+limit
print "assign url all that gnarly stuff for the query"
m.url=m.api+"/tracks.xml?q="+querystring+"&"+mid(m.ckey,2)+"&limit="+lim.tostr()+"&ofs="+ofs.tostr()
print "now set xfer url"
m.xfer.setURL(m.url)
print "now do the get to string thing"
m.xferResult= m.xfer.GetToString()
print "ok, skip printing result of transfer, this may be where it blows up?"
'print "transfer-result"+m.xferResult
print "ok well that didn't blow up so now do that parsing stuff"
if m.xmlTracklist.Parse(m.xferResult)
print "parse is true blue"
counter=0
print "counter="+counter.ToStr()
For Each track in m.xmlTrackList.track
?"************xmlcheck***************"
xmlcheck=m.xmlTrackList.track.GetNamedElements("stream-url").[counter].GetText()
?"***********************************"
if xmlcheck <> invalid and xmlcheck <> "" then
?"xml check success"
GetTrackSet(counter, track)
print m.TrackTitle+", "+m.TrackURL
posterlist.push(CreatePosterItems())
counter=counter+1
print "counter="+counter.ToStr()
else
?"xmlcheck failed"
end if
Next
End If
return posterlist
end function
Screenshades: The first Screensaver for Roku2!
Musiclouds: The best free internet music, on your Roku!
Ouroborialis: Psychedelic Screensaver for Roku!
0 Kudos
TheEndless
Channel Surfer

Re: XML validity testing again

I understand that, but you're calling GetTrackSet with parameters, and then parsing the XML again to pull the URL, which you just grabbed a few lines earlier. This seems redundant to me. You're reprocessing the XML a lot in your code, for no real reason. Did you look at the code I posted?
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
jbrave
Channel Surfer

Re: XML validity testing again

Yes, I'm looking at the code you wrote right now. I have some questions:

"TheEndless" wrote:
I really don't understand that [counter] part. And your outer look doesn't makes sense either, since you're not using "track". Try this instead...


so in GetTrackSet:

function getTrackSet(counter as integer, track as object) as object
m.TrackURL = m.xmlTrackList.track.GetNamedElements("stream-url").[counter].GetText()+m.ckey
m.TrackGenre=m.xmlTrackList.track.GetNamedElements("genre").[counter].GetText()
m.TrackDescription = m.xmlTrackList.track.GetNamedElements("description").[counter].GetText()
m.TrackCreated=m.xmlTrackList.track.GetNamedElements("created-at").[counter].GetText()
m.WaveformURL=m.xmlTracklist.track.GetNamedElements("waveform-url").[counter].GetText()+m.ckey
m.ArtworkURL=m.xmlTrackList.track.GetNamedElements("artwork-url").[counter].GetText()
if m.ArtworkURL="" then
m.ArtworkURL="pkg:/images/sc-roku-poster.png"
else
m.artworkURL=m.ArtworkURL+m.ckey
end if
print m.ArtworkURL

print type(m.artworkURL)
m.song.url = m.TrackURL+m.ckey
m.song.StreamFormat="mp3"

m.audioplayer.addcontent(m.song)
return m.song
End Function


I can replace this:

 m.TrackURL = m.xmlTrackList.track.GetNamedElements("stream-url").[counter].GetText()+m.ckey


with this:

m.TrackURL = track.GetNamedElements("stream-url").GetText()+m.ckey


?
Screenshades: The first Screensaver for Roku2!
Musiclouds: The best free internet music, on your Roku!
Ouroborialis: Psychedelic Screensaver for Roku!
0 Kudos
TheEndless
Channel Surfer

Re: XML validity testing again

You should be able to, yeah.. with all of the GetNamedElements() calls. Your "counter" method is working (sorta), because you're grabbing the n-th element in the list, but since you're incrementing counter on every track, there's a good possibility of it blowing up later in the loop, if any of the tracks don't contain one of the elements you're pulling. It'll also get out of sync as soon as it hits a track without one of the elements... For example...

Given this XML...

<tracklist>
<track>
<stream-url>blah 1</stream-url>
<genre>genre 1</genre>
<description>description 1</description>
</track>
<track>
<stream-url>blah 2</stream-url>
<description>description 2</description>
</track>
<track>
<stream-url>blah 3</stream-url>
<genre>genre 3</genre>
<description>description 1</description>
</track>
</tracklist>

xmlTrackList.track.GetNamedElements("stream-url") is going to return an roXMLList with 3 elements (blah 1, blah 2, blah 3), whereas xmlTrackList.track.GetNamedElements("genre") is going to return an roXMLList with 2 elements (genre 1 and genre 3). So a call to the second element in each list (via your counter) is going to return the stream url for track 2, but the genre for track 3. A call to the 3rd element in each list will return the stream url for track 3, and blow up when it tries to get the 3rd genre.

By calling GetNamedElements() on the specific track (via your For...Next loop), you'll limit those roXMLLists to elements beneath that track, so it will always have the correct value in index 0 (assuming the element exists on that track).
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
jbrave
Channel Surfer

Re: XML validity testing again

I'm wondering if there is a way to use encapsulation or something to create a method that would let me do an evaluation like this for all the returned xml so I don't have to have a check like this for each xml tag that I'm retrieving?

something like

m.xferResult= m.xfer.GetToString()
if m.xmlTracklist.Parse(m.xferResult)

For Each track in m.xmltracklist.track
taglist=track.extracttaglist() 'hypothetical function that I don't know how to write
xmlcheck=track.validate(taglist) 'hypothetical function that I'm not quite sure how to write


where it would validate that every xml tag is valid in each iteration of the loop, instead of having an if statement for each known xml tag? What If I want to check all xmlTags for validity even if I don't know what they are ahead of time?
Screenshades: The first Screensaver for Roku2!
Musiclouds: The best free internet music, on your Roku!
Ouroborialis: Psychedelic Screensaver for Roku!
0 Kudos