Forum Discussion

squirreltown's avatar
squirreltown
Roku Guru
12 years ago

XML to JSON

I would like to add some twitter functionality to my channel so my first step is needing to "fix" the SDK twitterOauth example which is currently broken since Twitter upgraded their API and now uses JSON instead of XML. My question for this first function is what is the JSON equivalent of xml.GetChildElements() since what i have there is not working
Function parse_status_response(json As Object, tweetArray As Object) As Void

tweetElements = json.GetChildElements()
tweetCount = 0

for each tweet in tweetElements

item = init_tweet_item()

item.Message = validstr(tweet.text.GetText())
item.UserName = validstr(tweet.user.screen_name.GetText())
item.ImageSource = validstr(tweet.user.profile_image_url.GetText())

tweetCount = tweetCount + 1
tweetArray.Push(item)
end for

End Function


And secondly Is there anything really obviously wrong with the start of this function (although the debugger wont let me get to this until the first question gets answered)

Function show_tweet_canvas() As Void

http = NewHttp(m.prefix+"1.1/statuses/user_timeline.json?screen_name=RokuPlayer")
oa = Oauth()
oa.sign(http,false)
rsp = http.getToStringWithTimeout(10)

json = ParseJson(rsp)

tweetArray = CreateObject("roArray", 100, true)
m.ParseTweets(json, tweetArray)
-----------------------




BTW the Oauth part is working fine.

Thanks

9 Replies

  • The return value from ParseJSON is just a normal AssociativeArray. You should be able to say

    for each tweet in json


    --Mark
  • Thanks Mark but i'm not clear how to implement that, with xml the hierarchy was:

    xml
    tweetElements = xml.getchildElements()
    for each tweet in tweetElements


    switching json for xml i have:

    json
    tweetElements =? (what goes here? another "for each"? And for each what of what?
    for each tweet in tweetElements'


    I changed
     tweetElements = xml.GetChildElements()

    to
    tweetElements = json

    which get me past that point but I'm getting a blank canvas no tweets yet.
    I am getting this message in the debugger and cant find what 400 means -
    Http: # 5975 done status: 400 

    Thanks
  • "squirreltown" wrote:
    Thanks Mark but i'm not clear how to implement that, with xml the hierarchy was:

    xml
    tweetElements = xml.getchildElements()
    for each tweet in tweetElements


    switching json for xml i have:

    json
    tweetElements =? (what goes here? another "for each"? And for each what of what?
    for each tweet in tweetElements


    It's not as simple as switching xml for json. They are different types, like Mark said. Parsing XML gives you a roXMLElement with its own set of member functions. ParseJSON() returns a plain old roAssociativeArray, so you can work with it like you would any other roAssociativeArray. roAssociativeArray doesn't have a function equivalent to GetChildElements(). To step through the members of a roAssociativeArray, you'd do something like:

    for each key in myAA
    ? key + ":" + myAA.Lookup(key) ' if the value isn't a string, this won't work, but you get the idea
    next


    Somewhere in the SDK sample code should be a function called PrintAA(). If you use that function on the result you get from ParseJSON(), you might get a better idea of what the structure looks like.
  • "squirreltown" wrote:

    I changed
     tweetElements = xml.GetChildElements()

    to
    tweetElements = json


    That's fine, although you don't really need the tweetElements variable. You can just write the for statement the way I quoted it above.

    "squirreltown" wrote:

    which get me past that point but I'm getting a blank canvas no tweets yet.
    I am getting this message in the debugger and cant find what 400 means -
    Http: # 5975 done status: 400 



    Status 400 is "Bad Request". It means the server is rejecting your request for some reason. You're sending something that twitter doesn't like.
    http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html has a list of all HTTP error codes.

    --Mark
  • Thank You Chris and Mark. I will work with it some more and I'm sure I'll be back. Chris, I have used that PrintAA function before, thats a real good idea, and thank you Mark for the codes, thats useful.
  • I misspoke earlier, the return value from ParseJSON is an roArray not an AA. So to look at the first item you just say "json[0]". The second is "json[1]", etc. Each of these items is an AA. The foreach statement will step through them. You can use PrintAA to examine the structure of each one: PrintAA(json[0]) etc.

    You probably want something like


    for each tweet in json
    item.Message = tweet["text"] ' or tweet.text
    item.UserName = tweet["user"]["name"] ' or tweet.user.name


    BTW if you're unsure of what a variable is, it's handy to do "print type(var)" in the debugger.

    --Mark
  • Thank you Mark. Between your guidance and flat-out guessing I've made it work. I will post the modified functions in a different thread if that can save anyone some effort.
    Have one remaining issue. I want to add any included photos with the tweets, but the key I need is 5 nested arrays deep and that seems to cause a syntax error if you go more than 3 levels (2 dots)

    What i need is:

    tweet.entities.media.List(0).media_url

    Is there a special way to handle this?

    Thanks

    AA printout below
    ---- AA ----
    retweeted: false
    source: <a href="http://www.apple.com" rel="nofollow">Photos on iOS</a>
    favorited: false
    lang: en
    coordinates: invalid
    geo: invalid
    in_reply_to_status_id: invalid
    place: invalid
    in_reply_to_screen_name: invalid
    in_reply_to_status_id_str: invalid
    retweet_count: 0
    possibly_sensitive: false
    entities: (assocarr)...
    hashtags: (list of 0)...
    urls: (list of 0)...
    user_mentions: (list of 0)...
    media: (list of 1)...
    List(0)= (assocarr)...
    expanded_url: http://twitter.com/XXXX/status/216669998213636096/photo/1
    media_url_https: https://pbs.twimg.com/media/AwHENyVCIAAT_eL.jpg
    display_url: pic.twitter.com/A3YDa8aT
    sizes: (assocarr)...
    small: (assocarr)...
    w: 340
    resize: fit
    h: 453
    thumb: (assocarr)...
    w: 150
    resize: crop
    h: 150
    large: (assocarr)...
    w: 384
    resize: fit
    h: 512
    medium: (assocarr)...
    w: 384
    resize: fit
    h: 512
    media_url: http://pbs.twimg.com/media/AwHENyVCIAAT_eL.jpg
  • "squirreltown" wrote:
    tweet.entities.media.List(0).media_url

    Your syntax error is most likely the parentheses. Those should be square brackets.

    EDIT: Actually, looking at the output, your brackets/parentheses are at the wrong level. I believe what you're looking for is:
    tweet.entities.media[0].media_url
  • Thank you Endless, i knew that List(0) line probably needed to be treated differently, now i know how.