urbanrider
urbanrider

Reputation: 231

Parsing iTunes Library XML in Cocoa

So I want to scan a large XML file (40mb) and as far as I understand I should use NSXMLParser to reduce the memory footprint. I want to check each song for a couple things, then if it passes all the criteria, write the songs into a new xml file.

I can load it in with NSXMLParser and do some basic reading of the file. So Im wondering how do I save each song as a temporary variable? And what kind of object should it be saved as (Im assuming something mutable, so I can keep adding more songs to the file before I write it to file).

    <key>Tracks</key>
<dict>
    <key>11072</key>
    <dict>
        <key>Track ID</key><integer>1107</integer>
        <key>Name</key><string>Kids with Guns (Hot Chip Remix)</string>
        <key>Artist</key><string>Gorillaz</string>
        <key>Album</key><string>D-Sides</string>
        <key>Genre</key><string>Britpop</string>
        <key>Kind</key><string>MPEG audio file</string>
        <key>Size</key><integer>844299</integer>
        <key>Total Time</key><integer>42971</integer>
        <key>Disc Number</key><integer>2</integer>
        <key>Disc Count</key><integer>2</integer>
        <key>Track Number</key><integer>6</integer>
        <key>Track Count</key><integer>9</integer>
        <key>Year</key><integer>2007</integer>
        <key>Date Modified</key><date>2008-10-30T02:44:58Z</date>
        <key>Date Added</key><date>2007-12-25T21:54:16Z</date>
        <key>Bit Rate</key><integer>153</integer>
        <key>Sample Rate</key><integer>44100</integer>
        <key>Comments</key><string> __FIXED__U74A0ECA</string>
        <key>Play Count</key><integer>1</integer>
        <key>Play Date</key><integer>3292750639</integer>
        <key>Play Date UTC</key><date>2008-05-04T20:57:19Z</date>
        <key>Skip Count</key><integer>1</integer>
        <key>Skip Date</key><date>2008-02-09T06:17:30Z</date>
        <key>Artwork Count</key><integer>2</integer>
        <key>Persistent ID</key><string>74A0ECAC8D</string>
        <key>Track Type</key><string>File</string>
        <key>Location</key><string>file://xxxxx/x/iTunes/Music/Gorillaz/D-Sides/2-06%20Kids%20with%20Guns%20(Hot%20Chip%20Remix).mp3</string>
        <key>File Folder Count</key><integer>5</integer>
        <key>Library Folder Count</key><integer>1</integer>
    </dict>

Upvotes: 4

Views: 890

Answers (1)

matt
matt

Reputation: 535890

Use any kind of object you like. You could use a dictionary, or you could make up your own class that reflects the structure that's convenient for you and reflects the structure of the data you're extracting. An obvious technique is that your top-level parser delegate has a property that's an NSMutableArray so you can just add things to it as you obtain them, and then the caller can fetch the resulting value, as I do in this code:

NSURL* url = // obtain xml URL
NSXMLParser* parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
MyPeopleParser* people = [[MyPeopleParser alloc] init];
[parser setDelegate: people];
[parser parse];

MyPeopleParser has an NSMutableArray of people called people. So now we can just fetch the value of that property (people.people, sorry about that). The array is now full of Person objects. But all of that is just an implementation detail. If you've figured out how to use NSXMLParser you're so far ahead of the game that the rest is gravy.

I'm not quite sure what you mean about writing to a file; the XML is a file. However, in my case I make my Person class archivable, so an NSArray of Person objects can be written directly to disk as a .plist.

Upvotes: 1

Related Questions