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: 
koshermetal
Visitor

Re: XML - Categories/Levels Question

I'm not sure if this is the right place for this, I'm sort of a noob but I'd like to think I have a brain 🙂

I'm using the videoplayer example files and seem to have it all figured out...except for the xml aspect (from what I gather). I am able to install the channel, but nothing happens when selected. My custom image shows fine though, since I edited the manifest file to point to my custom images, etc.

When debugging I get the following (amongst other stuff, I can post the entire thing if needed):
Syntax Error. (runtime error &h02) in .../pkg:/source/categoryFeed.brs(38)

along with
created feed connection for pkg:/xml/categories.xml
url: pkg:/xml/categories.xml
Took: 856ms
Can't parse feed


In the categoryfeed.brs file I have:
conn.UrlPrefix   = "pkg:/xml"
conn.UrlCategoryFeed = conn.UrlPrefix + "/categories.xml"


My categories.xml file looks like this, there is only one "categoryleaf" currently but I plan to add more and re-package the channel as I update: (I replaced my actual tltle with "TITLE" & description with "DESC" for this post and didn't put the entire URL of the images, etc. - just wanted to show the structure):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<categories>
<banner_ad
sd_img="http://dl.dropbox.com...." hd_img="http://dl.dropbox.com......"/>
<category title="Videos" description="DESC"
sd_img="http://dl.dropbox.com..."
hd_img="http://dl.dropbox.com....">
<categoryLeaf title="TITLE" description="DESC" feed="pkg:/xml/5lcl.xml"/>
</category>
</categories>



Is there something I'm missing? BTW...I'm using the SDK v29 that was provided on the dev site. Windows 7 w/ PuTTY as my telnet terminal. I have a Roku 2 XD Software v4.1

Thanks in advance for your help guys!
Free 24/7 Metal radio via web or smartphone
www.koshermetal.com
0 Kudos
renojim
Community Streaming Expert

Re: XML - Categories/Levels Question

RokuChris posted a good link for an XML validator: http://www.w3schools.com/xml/xml_validator.asp

Your XML seems to be fine, so I'm wondering if there's something wrong with what you've replaced with the ellipses.

Edit: It's not the XML. You can't do an roUrlTransfer from local storage. A quick hack (and it is a hack) is to replace:
rsp = http.GetToStringWithRetry()
with
rsp = ReadAsciiFile(http.Http.GetUrl())
in categoryFeed.brs.


-JT
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
koshermetal
Visitor

Re: XML - Categories/Levels Question

Well...there was an error coincidentally in the categories.xml file - there was an ampersand in the description, so thanks for helping me fix that. However...I still get syntax and parse errors. I validated both xml files in the xml directory and there are no errors. Below is the entire copy from the debugger.

34: Function get_category_names(categories As Object) As Dynamic
035:
036: categoryNames = CreateObject("roArray", 100, true)
037:
038: for each category in categories.kids
039: 'print category.Title
040: categoryNames.Push(category.Title)
041: next
042:
043: return categoryNames
044:
045: End Function
Syntax Error. (runtime error &h02) in .../pkg:/source/categoryFeed.brs(38)

038: for each category in categories.kids
Backtrace:
Function get_category_names(categories As <uninitialized>) As
file/line: /tmp/plugin/LDAAAA4Iq.../pkg:/source/categoryFeed.brs(38)
Function initcategorylist() As
file/line: /tmp/plugin/LDAAAA4Iqp1v/pkg:/source/appHomeScreen.brs(112)
Function showhomescreen(screen As ) As Integer
file/line: /tmp/plugin/LDAAAA4Iqp1v/pkg:/source/appHomeScreen.brs(39)
Function main() As
file/line: /tmp/plugin/LDAAAA4Iqp1v/pkg:/source/appMain.brs(20)

Local Variables:
categories &h0010 bsc:roInvalid, refcnt=1
global &h0020 rotINTERFACE:ifGlobal
m &h0010 bsc:roAssociativeArray, refcnt=3
categorynames &h0010 bsc:roArray, refcnt=1
category &h0000 <uninitialized> val:Uninitialized
BrightScript Debugger> ------ Running ------
created feed connection for pkg:/xml/categories.xml
url: pkg:/xml/categories.xml
Took: 867ms
Can't parse feed
BrightScript Micro Debugger.
Enter any BrightScript statement, debug commands, or HELP.

Current Function:
034: Function get_category_names(categories As Object) As Dynamic
035:
036: categoryNames = CreateObject("roArray", 100, true)
037:
038: for each category in categories.kids
039: 'print category.Title
040: categoryNames.Push(category.Title)
041: next
042:
043: return categoryNames
044:
045: End Function
Syntax Error. (runtime error &h02) in .../pkg:/source/categoryFeed.brs(38)

038: for each category in categories.kids
Backtrace:
Function get_category_names(categories As <uninitialized>) As
file/line: /tmp/plugin/NDAAAAdIW.../pkg:/source/categoryFeed.brs(38)
Function initcategorylist() As
file/line: /tmp/plugin/NDAAAAdIWH28/pkg:/source/appHomeScreen.brs(112)
Function showhomescreen(screen As ) As Integer
file/line: /tmp/plugin/NDAAAAdIWH28/pkg:/source/appHomeScreen.brs(39)
Function main() As
file/line: /tmp/plugin/NDAAAAdIWH28/pkg:/source/appMain.brs(20)

Local Variables:
categories &h0010 bsc:roInvalid, refcnt=1
global &h0020 rotINTERFACE:ifGlobal
m &h0010 bsc:roAssociativeArray, refcnt=3
categorynames &h0010 bsc:roArray, refcnt=1
category &h0000 <uninitialized> val:Uninitialized
BrightScript Debugger> BrightScript Debugger> BrightScript Debugger> ------ Running ------
created feed connection for pkg:/xml/categories.xml
url: pkg:/xml/categories.xml
Took: 54ms
Can't parse feed
Current Function:
034: Function get_category_names(categories As Object) As Dynamic
035:
036: categoryNames = CreateObject("roArray", 100, true)
037:
038: for each category in categories.kids
039: 'print category.Title
040: categoryNames.Push(category.Title)
041: next
042:
043: return categoryNames
044:
045: End Function
Syntax Error. (runtime error &h02) in .../pkg:/source/categoryFeed.brs(38)

038: for each category in categories.kids
Backtrace:
Function get_category_names(categories As <uninitialized>) As
file/line: /tmp/plugin/NDAAAAdIW.../pkg:/source/categoryFeed.brs(38)
Function initcategorylist() As
file/line: /tmp/plugin/NDAAAAdIWH28/pkg:/source/appHomeScreen.brs(112)
Function showhomescreen(screen As ) As Integer
file/line: /tmp/plugin/NDAAAAdIWH28/pkg:/source/appHomeScreen.brs(39)
Function main() As
file/line: /tmp/plugin/NDAAAAdIWH28/pkg:/source/appMain.brs(20)

Local Variables:
categories &h0010 bsc:roInvalid, refcnt=1
global &h0020 rotINTERFACE:ifGlobal
m &h0010 bsc:roAssociativeArray, refcnt=3
categorynames &h0010 bsc:roArray, refcnt=1
category &h0000 <uninitialized> val:Uninitialized
BrightScript Debugger>


Here is what the categoryfeed.brs file looks like, since it seems to be of relevance.
Function InitCategoryFeedConnection() As Object

conn = CreateObject("roAssociativeArray")

conn.UrlPrefix = "pkg:/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
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


Thanks again for your help!
Free 24/7 Metal radio via web or smartphone
www.koshermetal.com
0 Kudos
renojim
Community Streaming Expert

Re: XML - Categories/Levels Question

See my edited post above.

-JT
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
koshermetal
Visitor

Re: XML - Categories/Levels Question

Thanks JT!

That hack definitely did the trick, now I can start focusing on making sure it's how I want and make the necessary tweaks. You rule man!

BUT...since you say that it's a "hack", does that mean I may run into problems when I decide to submit it as a public channel? Meaning it won't get approved due to the "hack" code?

Thanks!
Free 24/7 Metal radio via web or smartphone
www.koshermetal.com
0 Kudos
renojim
Community Streaming Expert

Re: XML - Categories/Levels Question

The example code assumes your XML is hosted somewhere, not part of the package, and you really do want your XML to be retrieved from someplace unless you know your content will never change. If your XML is part of the package, you'd have to submit an updated channel every time you want to update your content.

The hack makes it so that only XML that is part of the package can be used and even if that's ok, you'd really want to rearrange/rewrite the code rather than have an object that appears to do an HTTP transfer, but really just reads from a local file.

I don't believe they analyze your code when you submit a channel. They just make sure it doesn't crash and follows the guidelines, so you're free to write code as ugly as you like.

-JT
Roku Community Streaming Expert

Help others find this answer and click "Accept as Solution."
If you appreciate my answer, maybe give me a Kudo.

I am not a Roku employee.
0 Kudos
koshermetal
Visitor

Re: XML - Categories/Levels Question

Ok...so I seem to be running into another syntax error issue and now the channel doesn't show when I install on the Roku Plugin Installation page. Any help would be greatly appreciated! I'm using SDK v29


Debug info (edit):
*** ERROR compiling /pkg:/source/appMain.brs:
Syntax Error. (compile error &h02) in ...SAOhC/pkg:/source/appMain.brs(41)
Syntax Error. (compile error &h02) in ...SAOhC/pkg:/source/appMain.brs(46)
*** ERROR compiling /pkg:/source/appMain.brs:
Syntax Error. (compile error &h02) in ...sQUZM/pkg:/source/appMain.brs(41)
Syntax Error. (compile error &h02) in ...sQUZM/pkg:/source/appMain.brs(46)


appMain.brs
'********************************************************************
'** Video Player Example Application - Main
'** November 2009
'** Copyright (c) 2009 Roku Inc. All Rights Reserved.
'********************************************************************

Sub Main()

'initialize theme attributes like titles, logos and overhang color
initTheme()

'prepare the screen for display and get ready to begin
screen=preShowHomeScreen("", "")
if screen=invalid then
print "unexpected error in preShowHomeScreen"
return
end if

'set to go, time to get started
showHomeScreen(screen)

End Sub


'*************************************************************
'** Set the configurable theme attributes for the application
'**
'** Configure the custom overhang and Logo attributes
'** Theme attributes affect the branding of the application
'** and are artwork, colors and offsets specific to the app
'*************************************************************

Sub initTheme()

app = CreateObject("roAppManager")
theme = CreateObject("roAssociativeArray")
theme.BackgroundColor = "#000000"
theme.OverhangOffsetSD_X = "72"
theme.OverhangOffsetSD_Y = "31"
theme.OverhangSliceSD = "pkg:/images/Overhang_KMBackground_SD.png"
theme.OverhangLogoSD =

theme.OverhangOffsetHD_X = "125"
theme.OverhangOffsetHD_Y = "35"
theme.OverhangSliceHD = "pkg:/images/Overhang_KMBackground_HD.png"
theme.OverhangLogoHD =

app.SetTheme(theme)

End Sub
Free 24/7 Metal radio via web or smartphone
www.koshermetal.com
0 Kudos
RokuMarkn
Visitor

Re: XML - Categories/Levels Question

When you see "syntax error" with a specific line number, you should go look at that line in your code. In your case, look at lines 41 and 46 and you'll see the problem.

--Mark
0 Kudos
koshermetal
Visitor

Re: XML - Categories/Levels Question

Forgive me, Mark. I'm on a PC using Windows and I see no lines in my code. All of the xml and brs files open in Notepad/Wordpad and I see no line numbers. Can you suggest an alternative method?

Thanks!
Free 24/7 Metal radio via web or smartphone
www.koshermetal.com
0 Kudos
gonzotek
Visitor

Re: XML - Categories/Levels Question

"koshermetal" wrote:
Forgive me, Mark. I'm on a PC using Windows and I see no lines in my code. All of the xml and brs files open in Notepad/Wordpad and I see no line numbers. Can you suggest an alternative method?

Thanks!
Use a code editor, rather than a text editor. I've used Notepad++ and Crimson Editor (a personal favorite, although it hasn't had a new release in ages and may be considered outdated). Eclipse is also an option (it's much more than a simple editor, and might be intimidating to get started with, but also offers many more features). There's an official plugin for Brightscript in Eclipse, linked at the top of the forum. Someone else has posted the code for syntax highlighting in Notepad++. I've also set up Crimson Editor to syntax highlight(I still need to clean it up a little before I can post the files).
Remoku.tv - A free web app for Roku Remote Control!
Want to control your Roku from nearly any phone, computer or tablet? Get started at http://help.remoku.tv
by Apps4TV - Applications for television and beyond: http://www.apps4tv.com
0 Kudos