Skip to content

Instantly share code, notes, and snippets.

@jchris
Created October 11, 2009 06:01
Show Gist options
  • Save jchris/207479 to your computer and use it in GitHub Desktop.
Save jchris/207479 to your computer and use it in GitHub Desktop.
// Copyright J. Chris Anderson 2007
// Retain this notice.
// Released under the LGPL 2.1
// http://creativecommons.org/licenses/LGPL/2.1/
XSPF = {
XMLfromString: function(string) {
if (window.ActiveXObject) {
var doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = "false";
doc.loadXML(string);
} else {
var parser = new DOMParser();
var doc = parser.parseFromString(string,"text/xml");
}
return doc;
},
toJSPF : function(xml_dom) {
var pl = this.parse_playlist(xml_dom);
return {playlist:pl};
},
parse_playlist : function(xspf) {
var playlist = new Object;
var xspf_playlist = xspf.getElementsByTagName('playlist')[0];
var trackList = xspf_playlist.getElementsByTagName('trackList')[0];
playlist.title = this.get_contents(xspf_playlist, 'title')[0];
playlist.creator = this.get_contents(xspf_playlist, 'creator')[0];
playlist.annotation = this.get_contents(xspf_playlist, 'annotation')[0];
playlist.info = this.get_contents(xspf_playlist, 'info')[0];
playlist.location = this.get_contents(xspf_playlist, 'location')[0];
playlist.identifier = this.get_contents(xspf_playlist, 'identifier')[0];
playlist.image = this.get_contents(xspf_playlist, 'image')[0];
playlist.date = this.get_contents(xspf_playlist, 'date')[0];
var attrs = this.getDirectChildrenByTagName(xspf_playlist,'attribution')[0];
playlist.attribution = this.getKeyValuePairs(attrs,['location','identifier']);
var linknodes = this.getDirectChildrenByTagName(xspf_playlist,'link');
playlist.link = this.getRelValuePairs(linknodes);
var metanodes = this.getDirectChildrenByTagName(xspf_playlist,'meta');
playlist.meta = this.getRelValuePairs(metanodes);
playlist.license = this.get_contents(xspf_playlist, 'license')[0];
playlist.extension = {};
var extnodes = this.getDirectChildrenByTagName(xspf_playlist,'extension');
for (var i=0; i < extnodes.length; i++) {
var node = extnodes[i];
var app = node.getAttribute('application');
if (app) {
playlist.extension[app] = playlist.extension[app] || [];
var extension = this.getExtensionReader(app,'playlist')(node);
playlist.extension[app].push(extension);
}
}
playlist.track = this.parse_tracks(trackList);
return playlist;
},
getExtensionReader: function(appname,pltr) {
if (XSPF.extensionReaders[pltr][appname]) {
return XSPF.extensionReaders[pltr][appname];
} else {
return XSPF.extensionReaders['_default'];
}
},
extensionReaders: {
playlist: {},
track: {},
_default: function(node) {
return XSPF.getUniqueKeyValuePairs(node);
}
},
getUniqueKeyValuePairs: function(node,filter) {
var result = {};
for (var y=0; y < node.childNodes.length; y++) {
var value = {};
var attr = node.childNodes[y];
if (attr.tagName) {
if (!filter || (filter && (filter.indexOf(attr.tagName) != -1))) {
result[attr.tagName] = this.node_text(attr);
}
}
}
return result;
},
getKeyValuePairs: function(node,filter,nowrap) {
var result = [];
for (var y=0; y < node.childNodes.length; y++) {
var value = {};
var attr = node.childNodes[y];
if (attr.tagName) {
if (!filter || (filter && (filter.indexOf(attr.tagName) != -1))) {
value[attr.tagName] = this.node_text(attr);
result.push(nowrap ? this.node_text(attr) : value);
}
}
}
return result;
},
getRelValuePairs: function(nodes) {
var result = [];
for (var y=0; y < nodes.length; y++) {
var ln = nodes[y];
var rel = ln.getAttribute('rel');
if (rel) {
var link = {};
link[rel] = this.node_text(ln)
result.push(link);
}
}
return result;
},
getDirectChildrenByTagName: function(source_node,tag_name) {
var nodes = source_node.childNodes;
var matches = [];
for (var i=0; i < nodes.length; i++) {
var node = nodes[i];
if (node.tagName == tag_name) {
matches.push(node);
}
}
return matches;
},
parse_tracks : function(xml) {
var xspf_tracks = this.getDirectChildrenByTagName(xml,'track');
var xspf_playlist_length = xspf_tracks.length;
var tracks = new Array;
for (var i=0; i < xspf_playlist_length; i++) {
var t = new Object;
var xspf_track = xspf_tracks[i];
t.annotation = this.get_contents(xspf_track, 'annotation')[0];
t.title = this.get_contents(xspf_track, 'title')[0];
t.creator = this.get_contents(xspf_track, 'creator')[0];
t.info = this.get_contents(xspf_track, 'info')[0];
t.image = this.get_contents(xspf_track, 'image')[0];
t.album = this.get_contents(xspf_track, 'album')[0];
t.trackNum = this.get_contents(xspf_track, 'trackNum')[0];
t.duration = this.get_contents(xspf_track, 'duration')[0];
t.location = this.getKeyValuePairs(xspf_track,['location'],true);
t.identifier = this.getKeyValuePairs(xspf_track,['identifier'],true);
var linknodes = this.getDirectChildrenByTagName(xspf_track,'link');
t.link = this.getRelValuePairs(linknodes);
var metanodes = this.getDirectChildrenByTagName(xspf_track,'meta');
t.meta = this.getRelValuePairs(metanodes);
t.extension = {};
var extnodes = this.getDirectChildrenByTagName(xspf_track,'extension');
for (var i=0; i < extnodes.length; i++) {
var node = extnodes[i];
var app = node.getAttribute('application');
if (app) {
t.extension[app] = t.extension[app] || [];
var extension = this.getExtensionReader(app,'track')(node);
t.extension[app].push(extension);
}
}
tracks.push(t);
}
return tracks;
},
get_contents : function(xml_node, tag) {
var xml_contents = xml_node.childNodes;
var contents = [];
for (var i=0; i < xml_contents.length; i++) {
var xml_content = xml_contents[i];
if (xml_content.tagName == tag) {
contents.push(this.node_text(xml_content));
}
}
return contents;
},
node_text : function(node) {
if (node.childNodes && node.childNodes.length > 1) {
return node.childNodes[1].nodeValue;
} else if (node.firstChild) {
return node.firstChild.nodeValue;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment