我正在学习可可/目标-c。现在我正在处理键/值编码。在阅读了Aaron的书和其他资料后,我认为我能够留下简单的例子并尝试一个复杂的例子......
我正在尝试阅读iTunes属性列表(iTunes Music Library.xml)。我想检索特定播放列表中的曲目。
可能每个人都知道,但是下面我放了一块xml:
<plist version="1.0">
<dict>
<key>Major Version</key><integer>1</integer>
...
<key>Playlists</key>
<array>
<dict>
<key>Name</key><string>Library</string>
<key>Master</key><true/>
<key>Playlist ID</key><integer>20117</integer>
...
<key>Playlist Items</key>
<array>
<dict>
<key>Track ID</key><integer>10281</integer>
</dict>
<dict>
<key>Track ID</key><integer>10283</integer>
</dict>
<dict>
<key>Track ID</key><integer>10285</integer>
</dict>
...
</array>
</dict>
<dict>
<key>Name</key><string>Classical Music</string>
<key>Playlist ID</key><integer>45013</integer>
...
</dict>
</array>
</dict>
</plist>
如您所见,播放列表作为字典存储在数组中,标识它的键位于其中,而不是前面的<key>
。
问题在于我无法弄清楚如何搜索另一个内部的密钥。
使用以下代码,我可以找到存储播放列表的数组,但是如何找到特定的<dict>
?在上面的plist中,字典有3个键来识别它:name,master和id。第一个播放列表的ID为20117,de第二个为45013.如何获取播放列表20117的曲目?
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:file];
NSArray *playlists = [rootDict objectForKey:@"Playlists"];
在Stackoverflow,我发现了这个post,但我不确定是否迭代数组并测试它是个好主意。
我很确定我可以使用valueForKeyPath
,但我无法弄明白该怎么做。
欢迎任何帮助。
TIA,
鲍勃
答案 0 :(得分:2)
假设您要搜索“播放列表ID”== 12194:
NSString *path = [[NSBundle mainBundle] pathForResource:@"iTunes Music Library" ofType:@"xml"];
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path];
NSArray *playlists = [rootDict objectForKey:@"Playlists"];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K == %@", @"Playlist ID",
[NSNumber numberWithInt:12194]];
NSArray *filteredArray = [playlists filteredArrayUsingPredicate:pred];
for (NSDictionary *dict in filteredArray) {
NSLog(@"Name = %@", [dict valueForKey:@"Name"]);
NSLog(@"Playlist ID = %@", [dict valueForKey:@"Playlist ID"]);
}
请注意,在这种情况下,快速枚举只返回一条记录(如果有的话)
答案 1 :(得分:0)
事实证明,NSFastEnumeration(你说for (NSDictionary *playlist in Playlists)
的那个很快,很好,很快。请参阅here了解详细信息。如果出于某些疯狂的原因,你真的不想这样做,你可以使用- (NSUInteger)indexOfObjectPassingTest:(BOOL (^)(id obj, NSUInteger idx, BOOL *stop))predicate
,但这可能会在数组上进行迭代.NSPredicate的东西或多或少地设计用于处理这类事情,但它们令人困惑且有限。基本上迭代事情真的很快,因为除非进行大型数据库样式优化,否则过滤抽象通常最终会迭代(通过使你构造+ destroy +与各种对象的接口来浪费效率)。
答案 2 :(得分:-1)
请参阅-propertyList
的{{1}}方法。