brucerothwell
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-06-2011
02:25 PM
XML Syntax for Deeper Category Levels
I am working with videoplayer from the SDK.
I would like to add additional levels of hierarchy in the categories. Right now, all I can seem to do is specify:
TOP LEVEL -> SUB-LEVEL -> CONTENT ITEMS
(where TOP LEVEL is the top "category", SUB-LEVEL is the "categoryLeaf" and CONTENT ITEMS are the items listed in the xml file referred to by the categoryLeaf.)
Is there a way to go deeper and wider, as in:
TOP LEVEL -> SUB-LEVEL1a -> SUB-LEVEL2 -> CONTENT ITEMS
----------- SUB-LEVEL1b -> SUB-LEVEL2 -> CONTENT ITEMS
Hopefully, you get what I mean.
Bruce Rothwell
I would like to add additional levels of hierarchy in the categories. Right now, all I can seem to do is specify:
TOP LEVEL -> SUB-LEVEL -> CONTENT ITEMS
(where TOP LEVEL is the top "category", SUB-LEVEL is the "categoryLeaf" and CONTENT ITEMS are the items listed in the xml file referred to by the categoryLeaf.)
Is there a way to go deeper and wider, as in:
TOP LEVEL -> SUB-LEVEL1a -> SUB-LEVEL2 -> CONTENT ITEMS
----------- SUB-LEVEL1b -> SUB-LEVEL2 -> CONTENT ITEMS
Hopefully, you get what I mean.
Bruce Rothwell
34 REPLIES 34
destruk
Streaming Star
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-06-2011
09:03 PM
Re: XML Syntax for Deeper Category Levels
Yes you could do that. Or you could include your entire schema layout in a single XML file.
brucerothwell
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-07-2011
01:20 PM
Re: XML Syntax for Deeper Category Levels
Thank you destruk, for the reply.
I guess I wasn't specific in my question.... can you, or anyone else, show me at least one example on how to do it?
And, as a bonus, can anyone help with what the syntax is for other variations on schema? (I have not been able to find this in the SDK documentation).
Thanks!!
-
Bruce Rothwell
I guess I wasn't specific in my question.... can you, or anyone else, show me at least one example on how to do it?
And, as a bonus, can anyone help with what the syntax is for other variations on schema? (I have not been able to find this in the SDK documentation).
Thanks!!
-
Bruce Rothwell
destruk
Streaming Star
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-07-2011
05:05 PM
Re: XML Syntax for Deeper Category Levels
I have created routines to read any kind of xml layout/schema I'd require for any channel I choose to create, but explaining how to do it is much more difficult.
Basically, for your top category xml you have that link to secondary category xml files. And those xml files point to other levels of files you want, and eventually you have a bottom content xml with the show/episode feed targets.
You can tell the two apart if you like by having your parser look for a heading you specifically create such as TargetType - xml would be another category list section, and anything else would be the end target like an mp4 or video or mp3.
To show off our work to other potential clients, we wanted to have a single application/channel that could show off every last feature Roku is capable of - all merged into a group of xml files, so we use the xml to set up the video feeds, mp3 files, video and audio playlists, gridscreens/poster screens, slideshows, single images, etc etc and it picks out what it needs for each feature section and creates the screen and different theming based entirely off the xml we feed into it. It can take months to make something like that, and whenever a new feature is added we expand it.
Basically, for your top category xml you have that link to secondary category xml files. And those xml files point to other levels of files you want, and eventually you have a bottom content xml with the show/episode feed targets.
You can tell the two apart if you like by having your parser look for a heading you specifically create such as TargetType - xml would be another category list section, and anything else would be the end target like an mp4 or video or mp3.
To show off our work to other potential clients, we wanted to have a single application/channel that could show off every last feature Roku is capable of - all merged into a group of xml files, so we use the xml to set up the video feeds, mp3 files, video and audio playlists, gridscreens/poster screens, slideshows, single images, etc etc and it picks out what it needs for each feature section and creates the screen and different theming based entirely off the xml we feed into it. It can take months to make something like that, and whenever a new feature is added we expand it.
brucerothwell
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-07-2011
05:57 PM
Re: XML Syntax for Deeper Category Levels
Hi destruk,
I understand what you are saying... that you really cannot share any actual examples, because your XML files are the bread-n-butter of your business.
However, can you explain a little bit more about this bit?...
>You can tell the two apart if you like by having your parser look for a heading you specifically create such as TargetType - xml would be another category list section, and anything else would be the end target like an mp4 or video or mp3.
I am not understanding where in the code to find where look for headings (I'm new tho this arena).
Thx,
Bruce
I understand what you are saying... that you really cannot share any actual examples, because your XML files are the bread-n-butter of your business.
However, can you explain a little bit more about this bit?...
>You can tell the two apart if you like by having your parser look for a heading you specifically create such as TargetType - xml would be another category list section, and anything else would be the end target like an mp4 or video or mp3.
I am not understanding where in the code to find where look for headings (I'm new tho this arena).
Thx,
Bruce
destruk
Streaming Star
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-07-2011
08:15 PM
Re: XML Syntax for Deeper Category Levels
Categoryfeed.brs is where the parsing is for the main xml file, so we used that to check for extra headers/entries in the xml file it downloads.
conn.LoadCategoryFeed=load_category_feed ' this points the load routine to function load_category_feed so this is where you might want to look
A short example would be something like this generic code you should already have in that file:
'followed by this unique/modified code
Then for displaying your screen you need to query the TargetType value of the item that was selected - if it's a "submenu" then have it create another poster screen and read out the next URL for the new screen's xml content, if it's a "video" then throw the selection information to the video player routine.
Something like that would do what you needed it to do with an xml like this:
You'll need to modify the channel script to work for your particular needs. You can have more than one xml parsing routine - the videoplayer example has one for the categories and a separate one for the shows (showfeed.brs).
conn.LoadCategoryFeed=load_category_feed ' this points the load routine to function load_category_feed so this is where you might want to look
A short example would be something like this generic code you should already have in that file:
Function load_category_feed(conn As Object) As Dynamic
http=NewHttp(conn.UrlCategoryFeed)
rsp=http.GetToStringWithRetry()
xml=CreateObject("roXMLElement")
If Not xml.Parse(rsp)
Print"Can't parse feed"
m.RoutineFailure=TRUE
Return invalid
End If
If islist(xml.entry)=FALSE
Print"invalid feed body"
Return invalid
End If
If xml.entry[0].GetName()<>"entry"
Print"no initial category tag"
Return invalid
End If
If xml.entry=invalid
Print"no categories tag"
Return invalid
End If
topNode=MakeEmptyCatNode()
topNode.Title="root"
topNode.isapphome=TRUE
categories=xml.GetChildElements()
Print"number of categories: "+itostr(categories.Count())
For Each e In categories
o=ParseCategoryNode(e) 'actual parsing happens here
If o<>invalid
topNode.AddKid(o)
Print"added new child node"
Else
Print"parse returned no child node"
End If
Next
Return topNode
End Function
'followed by this unique/modified code
Function ParseCategoryNode(xml As Object) As dynamic
o=init_category_item() 'setup defaults for an item
If xml.GetName()="entry"
o.TargetType=validstr(xml.targettype.GetText()) 'ADDED
o.TargetSource=validstr(xml.targetsource.GetText())
If o.TargetType="video"
'parse and read/import settings for a basic video file
o.Title=validstr(xml.Title.GetText()) 'Give the video icon a name to display on the screen
o.SDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
'for a single stream you'd just want a single entry for the media, for multiple streams parse with a loop for each media entry
o.Streamurls[0]=o.TargetSource
o.Bitrates[0]=strtoi(validstr(xml.Bitrate.GetText()))
o.StreamQualities[0]=validstr(xml.StreamQuality.GetText())
End If
If TargetType="submenu"
'parse and read/import settings for a submenu
o.SDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
o.Feed=o.TargetSource 'set up URL for submenu's XML file
o.Title=validstr(xml.Title.GetText()) 'Give the submenu icon a name to display on the screen
End If
End If
Return o
End Function
Then for displaying your screen you need to query the TargetType value of the item that was selected - if it's a "submenu" then have it create another poster screen and read out the next URL for the new screen's xml content, if it's a "video" then throw the selection information to the video player routine.
Something like that would do what you needed it to do with an xml like this:
<?xml version="1.0" encoding="UTF-8" ?>
<categories>
<entry>
<TargetType>submenu</TargetType>
<Title>My Submenu</Title>
<SDThumbnail>http://myserver.com/images/submenusd.png</SDThumbnail>
<HDThumbnail>http://myserver.com/images/submenuhd.png</HDThumbnail>
<TargetSource>http://myserver.com/xml/submenu.xml</TargetSource>
</entry>
<entry>
<TargetType>video</TargetType>
<Title>My Video</Title>
<SDThumbnail>http://myserver.com/images/myvideosd.png</SDThumbnail>
<HDThumbnail>http://myserver.com/images/myvideohd.png</HDThumbnail>
<TargetSource>http://myserver.com/content/myvideo.mp4</TargetSource>
<Bitrate>1000</Bitrate>
<StreamQuality>SD</StreamQuality>
</entry>
<entry>
<TargetType>submenu</TargetType>
<Title>More Videos</Title>
<SDThumbnail>http://myserver.com/images/morevideossd.png</SDThumbnail>
<HDThumbnail>http://myserver.com/images/morevideoshd.png</HDThumbnail>
<TargetSource>http://myserver.com/xml/morevideos.xml</TargetSource>
</entry>
</categories>
You'll need to modify the channel script to work for your particular needs. You can have more than one xml parsing routine - the videoplayer example has one for the categories and a separate one for the shows (showfeed.brs).
claudioc
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-13-2012
10:23 PM
Re: XML Syntax for Deeper Category Levels
i just wanted to add, a big thanks for this example man, im going to mess around with it now, this was a serious problem for me, i was considering making 2 versions of a channel because the content requirements were too rich and deep for the 3 level menus, so you seriously helped me out big time. This part of the documentation is lacking a bit, its a harder language to learn (brightscript) since its a combination of a # of things and not having a variety of information on these said languages makes the references alone sort of moot. but in any event thanks very much i know you wrote this back in september, but the truth is man you helping others even though you do this for a living is really cool. most of us just want something for our private use and so on. and your details wont effect your business in a negative way, take a look around man theres so many ads requesting a roku developer, and barely anyone ever hits these people up, so your good.
Claudio
Claudio
destruk
Streaming Star
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-13-2012
11:19 PM
Re: XML Syntax for Deeper Category Levels
You're welcome. Most of the professional channel developers I know, would want to help, but usually the Roku support team jumps in before anyone else sees the thread. 🙂
claudioc
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-13-2012
11:50 PM
Re: XML Syntax for Deeper Category Levels
hey i got a question actually, i tried to add the code u suggested following the spot you mentioned but when i send the source code over to the roku the channel no longer shows, and i made sure my old version would work correctly, so im thinking i broke something in the code, i used your example of what "should already be there" since mine was just a bit different, keep in mind im using a Roku 2 XS heres the way my categoryFeed.brs file looks, can you tell me what i did wrong, so that i can get the channel to show up, i changed NOTHING else other than what you suggested exactly:
categoryFeed.brs:
and just to mention it i used your xml syntax you clearly showed us how to add so we could do submenu or video, that part i believe couldnt be more clear so thank you there, but since the *.brs file seems to be not working correctly, and im not sure how to debug it honestly, i would love to know what i did wrong, so i could get the submenus working. also was i suppose to modify anything in the appmain.brs ? or anything else for that matter to accomplish what you explained, thank you very much for following up man i appreciate it very much, im working tirelessly to try and get this project finished, and i got all the art made, and video made and im just left with fixing the submenu levels and i can finish up. and i do realize mywebsitegoeshere.com is not correct i just shielded my website details. and in closing ALL im after changing from the videoplayer example is just having submenus like you explained, so i just need the code to work for that only.
Claudio
categoryFeed.brs:
'******************************************************
'** Video Player Example Application -- Category Feed
'** November 2009
'** Copyright (c) 2009 Roku Inc. All Rights Reserved.
'******************************************************
'******************************************************
' Set up the category feed connection object
' This feed provides details about top level categories
'******************************************************
Function InitCategoryFeedConnection() As Object
conn = CreateObject("roAssociativeArray")
conn.UrlPrefix = "mywebsitegoeshere.com/xml"
conn.UrlCategoryFeed = conn.UrlPrefix + "/categories.xml"
conn.Timer = CreateObject("roTimespan")
conn.LoadCategoryFeed = load_category_feed
conn.GetCategoryNames = get_category_names
print "created feed connection for " + conn.UrlCategoryFeed
return conn
End Function
'*********************************************************
'** Create an array of names representing the children
'** for the current list of categories. This is useful
'** for filling in the filter banner with the names of
'** all the categories at the next level in the hierarchy
'*********************************************************
Function get_category_names(categories As Object) As Dynamic
categoryNames = CreateObject("roArray", 100, true)
for each category in categories.kids
'print category.Title
categoryNames.Push(category.Title)
next
return categoryNames
End Function
'******************************************************************
'** Given a connection object for a category feed, fetch,
'** parse and build the tree for the feed. the results are
'** stored hierarchically with parent/child relationships
'** with a single default node named Root at the root of the tree
'******************************************************************
Function load_category_feed(conn As Object) As Dynamic
http=NewHttp(conn.UrlCategoryFeed)
rsp=http.GetToStringWithRetry()
xml=CreateObject("roXMLElement")
If Not xml.Parse(rsp)
Print"Can't parse feed"
m.RoutineFailure=TRUE
Return invalid
End If
If islist(xml.entry)=FALSE
Print"invalid feed body"
Return invalid
End If
If xml.entry[0].GetName()<>"entry"
Print"no initial category tag"
Return invalid
End If
If xml.entry=invalid
Print"no categories tag"
Return invalid
End If
topNode=MakeEmptyCatNode()
topNode.Title="root"
topNode.isapphome=TRUE
categories=xml.GetChildElements()
Print"number of categories: "+itostr(categories.Count())
For Each e In categories
o=ParseCategoryNode(e) 'actual parsing happens here
If o<>invalid
topNode.AddKid(o)
Print"added new child node"
Else
Print"parse returned no child node"
End If
Next
Return topNode
End Function
'******************************************************
'This Section Enables Multiple Tiers of Levels
'******************************************************
Function ParseCategoryNode(xml As Object) As dynamic
o=init_category_item() 'setup defaults for an item
If xml.GetName()="entry"
o.TargetType=validstr(xml.targettype.GetText()) 'ADDED
o.TargetSource=validstr(xml.targetsource.GetText())
If o.TargetType="video"
'parse and read/import settings for a basic video file
o.Title=validstr(xml.Title.GetText()) 'Give the video icon a name to display on the screen
o.SDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
'for a single stream you'd just want a single entry for the media, for multiple streams parse with a loop for each media entry
o.Streamurls[0]=o.TargetSource
o.Bitrates[0]=strtoi(validstr(xml.Bitrate.GetText()))
o.StreamQualities[0]=validstr(xml.StreamQuality.GetText())
End If
If TargetType="submenu"
'parse and read/import settings for a submenu
o.SDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
o.Feed=o.TargetSource 'set up URL for submenu's XML file
o.Title=validstr(xml.Title.GetText()) 'Give the submenu icon a name to display on the screen
End If
End If
Return o
End Function
'******************************************************
'MakeEmptyCatNode - use to create top node in the tree
'******************************************************
Function MakeEmptyCatNode() As Object
return init_category_item()
End Function
'***********************************************************
'Given the xml element to an <Category> tag in the category
'feed, walk it and return the top level node to its tree
'***********************************************************
Function ParseCategoryNode(xml As Object) As dynamic
o = init_category_item()
print "ParseCategoryNode: " + xml.GetName()
'PrintXML(xml, 5)
'parse the curent node to determine the type. everything except
'special categories are considered normal, others have unique types
if xml.GetName() = "category" then
print "category: " + xml@title + " | " + xml@description
o.Type = "normal"
o.Title = xml@title
o.Description = xml@Description
o.ShortDescriptionLine1 = xml@Title
o.ShortDescriptionLine2 = xml@Description
o.SDPosterURL = xml@sd_img
o.HDPosterURL = xml@hd_img
elseif xml.GetName() = "categoryLeaf" then
o.Type = "normal"
elseif xml.GetName() = "specialCategory" then
if invalid <> xml.GetAttributes() then
for each a in xml.GetAttributes()
if a = "type" then
o.Type = xml.GetAttributes()[a]
print "specialCategory: " + xml@type + "|" + xml@title + " | " + xml@description
o.Title = xml@title
o.Description = xml@Description
o.ShortDescriptionLine1 = xml@Title
o.ShortDescriptionLine2 = xml@Description
o.SDPosterURL = xml@sd_img
o.HDPosterURL = xml@hd_img
endif
next
endif
else
print "ParseCategoryNode skip: " + xml.GetName()
return invalid
endif
'only continue processing if we are dealing with a known type
'if new types are supported, make sure to add them to the list
'and parse them correctly further downstream in the parser
while true
if o.Type = "normal" exit while
if o.Type = "special_category" exit while
print "ParseCategoryNode unrecognized feed type"
return invalid
end while
'get the list of child nodes and recursed
'through everything under the current node
for each e in xml.GetBody()
name = e.GetName()
if name = "category" then
print "category: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.ShortDescriptionLine1 = xml@Description
kid.SDPosterURL = xml@sd_img
kid.HDPosterURL = xml@hd_img
o.AddKid(kid)
elseif name = "categoryLeaf" then
print "categoryLeaf: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.Feed = e@feed
o.AddKid(kid)
elseif name = "specialCategory" then
print "specialCategory: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.sd_img = e@sd_img
kid.hd_img = e@hd_img
kid.Feed = e@feed
o.AddKid(kid)
endif
next
return o
End Function
'******************************************************
'Initialize a Category Item
'******************************************************
Function init_category_item() As Object
o = CreateObject("roAssociativeArray")
o.Title = ""
o.Type = "normal"
o.Description = ""
o.Kids = CreateObject("roArray", 100, true)
o.Parent = invalid
o.Feed = ""
o.IsLeaf = cn_is_leaf
o.AddKid = cn_add_kid
return o
End Function
'********************************************************
'** Helper function for each node, returns true/false
'** indicating that this node is a leaf node in the tree
'********************************************************
Function cn_is_leaf() As Boolean
if m.Kids.Count() > 0 return true
if m.Feed <> "" return false
return true
End Function
'*********************************************************
'** Helper function for each node in the tree to add a
'** new node as a child to this node.
'*********************************************************
Sub cn_add_kid(kid As Object)
if kid = invalid then
print "skipping: attempt to add invalid kid failed"
return
endif
kid.Parent = m
m.Kids.Push(kid)
End Sub
and just to mention it i used your xml syntax you clearly showed us how to add so we could do submenu or video, that part i believe couldnt be more clear so thank you there, but since the *.brs file seems to be not working correctly, and im not sure how to debug it honestly, i would love to know what i did wrong, so i could get the submenus working. also was i suppose to modify anything in the appmain.brs ? or anything else for that matter to accomplish what you explained, thank you very much for following up man i appreciate it very much, im working tirelessly to try and get this project finished, and i got all the art made, and video made and im just left with fixing the submenu levels and i can finish up. and i do realize mywebsitegoeshere.com is not correct i just shielded my website details. and in closing ALL im after changing from the videoplayer example is just having submenus like you explained, so i just need the code to work for that only.
Claudio
claudioc
Visitor
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
03-13-2012
11:58 PM
Re: XML Syntax for Deeper Category Levels
well.. i figured out the debugger, and found an error, heres the problem man, i had the same syntax written twice:
Function ParseCategoryNode(xml As Object) As dynamic
so what i tried to do, was combine it like the following with the previously used command:
and i tried your other code in place of what was already there as you first mentioned, but it returns errors so i left my original and tested that, plus commented out the 5 lines with ' since it was just a command if something failed to work so i figured worth commenting out to test. In any event, no matter what i do, the new commands for submenu and video target type and such, the xml files just wont parse because its missing the <feed></feed> but obviously thats not how you explained to use the xml so im confused bud. here is my entire *.brs file as i have it now besides the specific part i showed you just so i could explain what i did to implement what you showed me:
I hope you can shed some light on my mistake here. i feel like considering the directions initially given didnt really say you will have a command like this already in your example, so you need to combine with that already used function in some way, i did my best to wing it and try and combine it with that function, and i get no actual errors when viewing the debug screen so i assume that part is ok.. so perhaps something is needed on the ShowFeed.brs or something but i been at this for like 8 hours straight and im getting no where unfortunately. so ill wait for a response 😆
Claudio
Function ParseCategoryNode(xml As Object) As dynamic
so what i tried to do, was combine it like the following with the previously used command:
Function ParseCategoryNode(xml As Object) As dynamic
o = init_category_item()
print "ParseCategoryNode: " + xml.GetName()
'PrintXML(xml, 5)
'parse the curent node to determine the type. everything except
'special categories are considered normal, others have unique types
if xml.GetName() = "category" then
print "category: " + xml@title + " | " + xml@description
o.Type = "normal"
o.Title = xml@title
o.Description = xml@Description
o.ShortDescriptionLine1 = xml@Title
o.ShortDescriptionLine2 = xml@Description
o.SDPosterURL = xml@sd_img
o.HDPosterURL = xml@hd_img
elseif xml.GetName() = "categoryLeaf" then
o.Type = "normal"
elseif xml.GetName() = "specialCategory" then
if invalid <> xml.GetAttributes() then
for each a in xml.GetAttributes()
if a = "type" then
o.Type = xml.GetAttributes()[a]
print "specialCategory: " + xml@type + "|" + xml@title + " | " + xml@description
o.Title = xml@title
o.Description = xml@Description
o.ShortDescriptionLine1 = xml@Title
o.ShortDescriptionLine2 = xml@Description
o.SDPosterURL = xml@sd_img
o.HDPosterURL = xml@hd_img
endif
next
endif
else
print "ParseCategoryNode skip: " + xml.GetName()
return invalid
endif
'only continue processing if we are dealing with a known type
'if new types are supported, make sure to add them to the list
'and parse them correctly further downstream in the parser
while true
if o.Type = "normal" exit while
if o.Type = "special_category" exit while
print "ParseCategoryNode unrecognized feed type"
return invalid
end while
'get the list of child nodes and recursed
'through everything under the current node
for each e in xml.GetBody()
name = e.GetName()
if name = "category" then
print "category: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.ShortDescriptionLine1 = xml@Description
kid.SDPosterURL = xml@sd_img
kid.HDPosterURL = xml@hd_img
o.AddKid(kid)
elseif name = "categoryLeaf" then
print "categoryLeaf: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.Feed = e@feed
o.AddKid(kid)
elseif name = "specialCategory" then
print "specialCategory: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.sd_img = e@sd_img
kid.hd_img = e@hd_img
kid.Feed = e@feed
o.AddKid(kid)
endif
next
return o
o=init_category_item() 'setup defaults for an item
If xml.GetName()="entry"
o.TargetType=validstr(xml.targettype.GetText()) 'ADDED
o.TargetSource=validstr(xml.targetsource.GetText())
If o.TargetType="video"
'parse and read/import settings for a basic video file
o.Title=validstr(xml.Title.GetText()) 'Give the video icon a name to display on the screen
o.SDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
'for a single stream you'd just want a single entry for the media, for multiple streams parse with a loop for each media entry
o.Streamurls[0]=o.TargetSource
o.Bitrates[0]=strtoi(validstr(xml.Bitrate.GetText()))
o.StreamQualities[0]=validstr(xml.StreamQuality.GetText())
End If
If TargetType="submenu"
'parse and read/import settings for a submenu
o.SDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
o.Feed=o.TargetSource 'set up URL for submenu's XML file
o.Title=validstr(xml.Title.GetText()) 'Give the submenu icon a name to display on the screen
End If
End If
Return o
End Function
and i tried your other code in place of what was already there as you first mentioned, but it returns errors so i left my original and tested that, plus commented out the 5 lines with ' since it was just a command if something failed to work so i figured worth commenting out to test. In any event, no matter what i do, the new commands for submenu and video target type and such, the xml files just wont parse because its missing the <feed></feed> but obviously thats not how you explained to use the xml so im confused bud. here is my entire *.brs file as i have it now besides the specific part i showed you just so i could explain what i did to implement what you showed me:
'******************************************************
'** Video Player Example Application -- Category Feed
'** November 2009
'** Copyright (c) 2009 Roku Inc. All Rights Reserved.
'******************************************************
'******************************************************
' Set up the category feed connection object
' This feed provides details about top level categories
'******************************************************
Function InitCategoryFeedConnection() As Object
conn = CreateObject("roAssociativeArray")
conn.UrlPrefix = "you-might-get.strangled.net/xml"
conn.UrlCategoryFeed = conn.UrlPrefix + "/categories.xml"
conn.Timer = CreateObject("roTimespan")
conn.LoadCategoryFeed = load_category_feed
conn.GetCategoryNames = get_category_names
print "created feed connection for " + conn.UrlCategoryFeed
return conn
End Function
'*********************************************************
'** Create an array of names representing the children
'** for the current list of categories. This is useful
'** for filling in the filter banner with the names of
'** all the categories at the next level in the hierarchy
'*********************************************************
Function get_category_names(categories As Object) As Dynamic
categoryNames = CreateObject("roArray", 100, true)
for each category in categories.kids
'print category.Title
categoryNames.Push(category.Title)
next
return categoryNames
End Function
'******************************************************************
'** Given a connection object for a category feed, fetch,
'** parse and build the tree for the feed. the results are
'** stored hierarchically with parent/child relationships
'** with a single default node named Root at the root of the tree
'******************************************************************
Function load_category_feed(conn As Object) As Dynamic
http = NewHttp(conn.UrlCategoryFeed)
Dbg("url: ", http.Http.GetUrl())
m.Timer.Mark()
rsp = http.GetToStringWithRetry()
Dbg("Took: ", m.Timer)
m.Timer.Mark()
xml=CreateObject("roXMLElement")
if not xml.Parse(rsp) then
print "Can't parse feed"
return invalid
endif
Dbg("Parse Took: ", m.Timer)
m.Timer.Mark()
if xml.category = invalid then
print "no categories tag"
return invalid
endif
if islist(xml.category) = false then
print "invalid feed body"
return invalid
endif
if xml.category[0].GetName() <> "category" then
print "no initial category tag"
return invalid
endif
topNode = MakeEmptyCatNode()
topNode.Title = "root"
topNode.isapphome = true
print "begin category node parsing"
categories = xml.GetChildElements()
print "number of categories: " + itostr(categories.Count())
for each e in categories
o = ParseCategoryNode(e)
if o <> invalid then
topNode.AddKid(o)
print "added new child node"
else
print "parse returned no child node"
endif
next
Dbg("Traversing: ", m.Timer)
return topNode
End Function
'******************************************************
'MakeEmptyCatNode - use to create top node in the tree
'******************************************************
Function MakeEmptyCatNode() As Object
return init_category_item()
End Function
'***********************************************************
'Given the xml element to an <Category> tag in the category
'feed, walk it and return the top level node to its tree
'***********************************************************
Function ParseCategoryNode(xml As Object) As dynamic
o = init_category_item()
print "ParseCategoryNode: " + xml.GetName()
'PrintXML(xml, 5)
'parse the curent node to determine the type. everything except
'special categories are considered normal, others have unique types
if xml.GetName() = "category" then
print "category: " + xml@title + " | " + xml@description
o.Type = "normal"
o.Title = xml@title
o.Description = xml@Description
o.ShortDescriptionLine1 = xml@Title
o.ShortDescriptionLine2 = xml@Description
o.SDPosterURL = xml@sd_img
o.HDPosterURL = xml@hd_img
elseif xml.GetName() = "categoryLeaf" then
o.Type = "normal"
elseif xml.GetName() = "specialCategory" then
if invalid <> xml.GetAttributes() then
for each a in xml.GetAttributes()
if a = "type" then
o.Type = xml.GetAttributes()[a]
print "specialCategory: " + xml@type + "|" + xml@title + " | " + xml@description
o.Title = xml@title
o.Description = xml@Description
o.ShortDescriptionLine1 = xml@Title
o.ShortDescriptionLine2 = xml@Description
o.SDPosterURL = xml@sd_img
o.HDPosterURL = xml@hd_img
endif
next
endif
else
print "ParseCategoryNode skip: " + xml.GetName()
return invalid
endif
'only continue processing if we are dealing with a known type
'if new types are supported, make sure to add them to the list
'and parse them correctly further downstream in the parser
while true
if o.Type = "normal" exit while
if o.Type = "special_category" exit while
print "ParseCategoryNode unrecognized feed type"
return invalid
end while
'get the list of child nodes and recursed
'through everything under the current node
for each e in xml.GetBody()
name = e.GetName()
if name = "category" then
print "category: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.ShortDescriptionLine1 = xml@Description
kid.SDPosterURL = xml@sd_img
kid.HDPosterURL = xml@hd_img
o.AddKid(kid)
elseif name = "categoryLeaf" then
print "categoryLeaf: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.Feed = e@feed
o.AddKid(kid)
elseif name = "specialCategory" then
print "specialCategory: " + e@title + " [" + e@description + "]"
kid = ParseCategoryNode(e)
kid.Title = e@title
kid.Description = e@Description
kid.sd_img = e@sd_img
kid.hd_img = e@hd_img
kid.Feed = e@feed
o.AddKid(kid)
endif
next
return o
o=init_category_item() 'setup defaults for an item
If xml.GetName()="entry"
o.TargetType=validstr(xml.targettype.GetText()) 'ADDED
o.TargetSource=validstr(xml.targetsource.GetText())
If o.TargetType="video"
'parse and read/import settings for a basic video file
o.Title=validstr(xml.Title.GetText()) 'Give the video icon a name to display on the screen
o.SDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
'for a single stream you'd just want a single entry for the media, for multiple streams parse with a loop for each media entry
o.Streamurls[0]=o.TargetSource
o.Bitrates[0]=strtoi(validstr(xml.Bitrate.GetText()))
o.StreamQualities[0]=validstr(xml.StreamQuality.GetText())
End If
If TargetType="submenu"
'parse and read/import settings for a submenu
o.SDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for SD mode
o.HDThumbmail=validstr(xml.SDThumbnail.GetText()) 'give the submenu a thumbnail image for HD mode
o.Feed=o.TargetSource 'set up URL for submenu's XML file
o.Title=validstr(xml.Title.GetText()) 'Give the submenu icon a name to display on the screen
End If
End If
Return o
End Function
'******************************************************
'Initialize a Category Item
'******************************************************
Function init_category_item() As Object
o = CreateObject("roAssociativeArray")
o.Title = ""
o.Type = "normal"
o.Description = ""
o.Kids = CreateObject("roArray", 100, true)
o.Parent = invalid
o.Feed = ""
o.IsLeaf = cn_is_leaf
o.AddKid = cn_add_kid
return o
End Function
'********************************************************
'** Helper function for each node, returns true/false
'** indicating that this node is a leaf node in the tree
'********************************************************
Function cn_is_leaf() As Boolean
if m.Kids.Count() > 0 return true
if m.Feed <> "" return false
return true
End Function
'*********************************************************
'** Helper function for each node in the tree to add a
'** new node as a child to this node.
'*********************************************************
Sub cn_add_kid(kid As Object)
if kid = invalid then
print "skipping: attempt to add invalid kid failed"
return
endif
kid.Parent = m
m.Kids.Push(kid)
End Sub
I hope you can shed some light on my mistake here. i feel like considering the directions initially given didnt really say you will have a command like this already in your example, so you need to combine with that already used function in some way, i did my best to wing it and try and combine it with that function, and i get no actual errors when viewing the debug screen so i assume that part is ok.. so perhaps something is needed on the ShowFeed.brs or something but i been at this for like 8 hours straight and im getting no where unfortunately. so ill wait for a response 😆
Claudio