make XML your ■■■■■!
Are you a plugin developer? Do you parse a lot of XML data (maybe from api calls)? Are you sick of having to messily xpath out every damn element by hand, while JSON users point at you and laugh? Does this powerlessness over your data structures lead to feelings of inadequacy? Well now thanks to the magic of [lxml objectify](http://codespeak.net/lxml/objectify.html), you have the power take control of your life, slim your code, satisfy your wife, and shove your superiority in your co-workers faces once again.
this will be in an upcoming framework update, probably shipping when plex .9 is public, but i thought I'd tease this early so it doesn't get overlooked, as you'll see it has the potential to make your like a lot easier.
basically its just 3 new methods for the framework's XML module, XML.ObjectFromString, XML.ObjectFromURL, and XML.StringFromObject. this is just a small wrapper for the underlying lxml objectify module, see http://codespeak.net/lxml/objectify.html for full docs on it, but basically, it presents structured XML data as a python object tree with the node contents data-bound as standard python types.
here's what it looks like in framework v1.
<br />
def ObjectFromString(string):<br />
"""Return a pyhon object hierarchy represnting the deserialized and data bound XML tree.<br />
<br />
wrapper for lxml objectify module, see http://codespeak.net/lxml/objectify.html for full documentation<br />
is only intended to be used with well formed valid XML, do not attempt with HTML or mixed contents.<br />
<br />
"""<br />
return objectify.fromstring(string)<br />
<br />
def ObjectFromURL(url, values=None, headers={}, cacheTime=None, autoUpdate=False, encoding=None, errors=None):<br />
"""Perform a HTTP request and return a python object representation of the fetched XML"""<br />
return ObjectFromString(HTTP.Request(url, values, headers, cacheTime, autoUpdate, encoding, errors))<br />
<br />
def StringFromObject(obj, encoding="utf8"):<br />
"""Return a string of the serialized XML data"""<br />
return etree.tostring(obj, pretty_print=Plugin.Debug, encoding=encoding)<br />
Not very complicated, and quite similar to the existing lxml wrappers. but what does this mean for you the plugin dev? Well it means that with valid, well-formed xml (do not attempt with html), you can throw away all those crazy messy xpaths, and use your XML in a very simple, object oriented, pythonic way, no more painfully hand-parsing XML trees.
well, it'll be easier to show you a real example. this is from my in-progress free music archive plugin (which you can see [here](http://github.com/sansnipple/plex-FMA).)
i can now replace this whole giant mess:
<br />
results = XML.ElementFromURL(url , errors="ignore")<br />
for i in range(len(results.xpath("//dataset/value"))):<br />
track = {}<br />
track["track_id"] = results.xpath("//dataset/value[%i]/track_id//text()" % (i+1))[0]<br />
track["track_url"] = results.xpath("//dataset/value[%i]/track_url//text()" % (i+1))[0]<br />
track["track_title"] = results.xpath("//dataset/value[%i]/track_title//text()" % (i+1))[0]<br />
track["artist_name"] = results.xpath("//dataset/value[%i]/artist_name//text()" % (i+1))[0]<br />
track["artist_id"] = results.xpath("//dataset/value[%i]/artist_id//text()" % (i+1))[0]<br />
track["album_title"] = results.xpath("//dataset/value[%i]/album_title//text()" % (i+1))[0]<br />
track["album_id"] = results.xpath("//dataset/value[%i]/album_id//text()" % (i+1))[0]<br />
# please please no index errors<br />
<br />
dir.Append(Function(TrackItem(getTrack, title=track["track_title"], artist=track["artist_name"], album=track["album_title"], contextKey=track), ext="mp3", url=track["track_url"]))<br />
with just THIS:
<br />
data = XML.ObjectFromURL(url)<br />
for track in data.dataset.value:<br />
dir.Append(Function(TrackItem(getTrack, title=track.track_title, artist=track.artist_name, album=track.album_title), ext="mp3", url=track.track_url))<br />
12 lines down to 3, and all the xpath headaches gone. yes an extreme example, but you get the point. feel the awesomeness?