如何查找特定键/值(属性列表)

时间:2010-05-22 23:42:21

标签: objective-c itunes plist

我正在学习可可/目标-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,

鲍勃

3 个答案:

答案 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}}方法。