Import iTunes xml data and convert it into a dataset or table
We can start by importing the file as an XMLObject
:
$url = "https://dl.dropboxusercontent.com/u/1012958/iTunes%20Library.xml";
$xml = Import[$url, {"XML", "XMLObject"}];
Short[$xml, 4]
(* XMLObject[Document][
{ XMLObject[Declaration][Version->1.0,Encoding->UTF-8]
, XMLObject[Doctype][plist,Public->-//Apple Computer//DTD PLIST 1.0//EN,<<1>>}
, XMLElement[plist,{version->1.0},{<<1>>}], {}, Valid->True ]
*)
The result is the XML document transformed into a Mathematica expression that is amenable to further transformation. Let's define a transformation from the XMLObject into a dataset. The iTunes file (an Apple plist file) is essentially a big nested hierarchy of associations, with the odd list thrown in:
itunesXmlToDataset[xml_] :=
Block[{XMLElement}
, XMLElement["plist", _, {c_}] := Dataset @ c
; XMLElement["dict", _, c_] := <| Rule @@@ Partition[c, 2] |>
; XMLElement["array", _, c_] := c
; XMLElement["key"|"string"|"data", _, {c_}] := c
; XMLElement["integer", _, {c_}] := FromDigits @ c
; XMLElement["date", _, {c_}] := DateObject @ c
; XMLElement["true", _, {}] := True
; XMLElement["false", _, {}] := False
; XMLElement[t_, _, {c_, ___}] := (Message[itunesXmlToDataset::ignored, t]; c)
; xml[[2]]
]
itunesXmlToDataset::ignored = "Ignored unexpected XML element: ``";
This will create the dataset we want:
$dataset = itunesXmlToDataset[$xml]
We can then query, say, for a list of all tracks along with their album and artist:
$dataset["Tracks", All, {"Name", "Album", "Artist"}]
... or perhaps for the playlists along with the number of songs in each:
$dataset[
"Playlists"
, All
, <| "Name" -> "Name", "Songs" -> "Playlist Items" /* Length |>
]
Had to add the "ReadDTD" -> False
option to
$xml = Import[
"/Volumes/WDC3TBRAID/Downloads/iTunes Music Library.xml", {"XML",
"XMLObject"}, "ReadDTD" -> False]
to get WReach's solution to work with Mathematica 11.0. Rest of his solution works fine after that.