我是XPath和xml解析的新手。我阅读了一些文档,但无法找到解决问题的方法。我的.xml看起来像这样(fyi:它是“iTunes Music Library.xml”的播放列表部分):
<dict>
<array>
<dict>
<key>Name</key><string>Playlist 1</string>
<key>Playlist ID</key><integer>187826</integer>
<key>Playlist Persistent ID</key><string>04250E0617138909</string>
<key>All Items</key><true/>
<key>Playlist Items</key>
<array>
<dict>
<key>Track ID</key><integer>11111</integer>
</dict>
<dict>
<key>Track ID</key><integer>22222</integer>
</dict>
</array
</dict>
<dict>
<key>Name</key><string>Playlist 2</string>
<key>Playlist ID</key><integer>187826</integer>
<key>Playlist Persistent ID</key><string>04250E0617138909</string>
<key>All Items</key><true/>
<key>Playlist Items</key>
<array>
<dict>
<key>Track ID</key><integer>23456</integer>
</dict>
<dict>
<key>Track ID</key><integer>34567</integer>
</dict>
</array
</dict>
</dict>
我的输入是一个包含播放列表名称的字符串。现在这就是我想要输出的内容:与该特定播放列表相关的所有songID。不幸的是,该名称不是例如 array 或第一个 dict 的属性。这就是我所拥有的(java-code):
ap.selectXPath("//dict/array/dict/string[1][text()=\"" + playlistName + "\"]");
当然,这只是给了我播放列表名称。那么从现在开始如何进行?我想到了这样:解析文件,直到解析器达到所需名称:
ap.selectXPath("//dict/array/dict[" + count++ +"]/string[1]");
带有“int count”。然后使用适当的查询从该位置重新开始。然而,这似乎并不优雅或高效。
长话短说:是否有XPath查询来满足我的要求?
答案 0 :(得分:1)
dict
元素以plist格式工作的方式是交替的元素对,每个值都是其key
的第一个兄弟元素。因此,对于给定的密钥,您可以访问该值
key[. = 'Entry name']/following-sibling::*[1]
因此,对于您感兴趣的特定示例,“播放列表1”的dict
元素是
/dict/array/dict[key[. = 'Name']/following-sibling::*[1] = 'Playlist 1']
其跟踪列表array
是
/dict/array/dict[key[. = 'Name']/following-sibling::*[1] = 'Playlist 1']
/key[. = 'Playlist Items']/following-sibling::*[1]
然后提供曲目ID的integer
元素集将是
/dict/array/dict[key[. = 'Name']/following-sibling::*[1] = 'Playlist 1']
/key[. = 'Playlist Items']/following-sibling::*[1]
/dict/key[. = 'Track ID']/following-sibling::*[1]
如果您从用户输入中获取播放列表名称并且它们可能包含单引号或双引号字符,请务必小心。您没有说明您正在使用哪个库,但如果它支持定义变量,那么您应该使用该机制来注入您的值,而不是依赖字符串连接来构建表达式。