2

一般来说,我是 XPath 和 xml 解析的新手。我阅读了一些文档,但找不到解决我的问题的方法。我的 .xml 看起来像这样(仅供参考:它是“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>

我的输入是一个包含播放列表名称的字符串。现在这是我想要的输出:与该特定播放列表相关的所有歌曲 ID。不幸的是,名称不是例如array或第一个dict的属性。这是我得到的(java代码):

ap.selectXPath("//dict/array/dict/string[1][text()=\"" + playlistName + "\"]");

当然,这只是给了我我的播放列表名称。那么从现在开始如何进行呢?我想到了:像这样解析文件,直到解析器达到所需的名称:

ap.selectXPath("//dict/array/dict[" + count++ +"]/string[1]");

带有“整数计数”。然后使用适当的查询从该位置重新开始。再说一次,这似乎并不优雅或高效。

长话短说:是否有 XPath 查询可以满足我的要求?

4

1 回答 1

1

元素在 plist 格式中的工作方式dict是交替成对的元素,每个值都是其key. 因此,对于给定的键,您可以将值访问为

key[. = 'Entry name']/following-sibling::*[1]

因此,对于您感兴趣的特定示例,dict“播放列表 1”的元素是

/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]

然后integer给出轨道 ID 的元素集将是

/dict/array/dict[key[. = 'Name']/following-sibling::*[1] = 'Playlist 1']
  /key[. = 'Playlist Items']/following-sibling::*[1]
  /dict/key[. = 'Track ID']/following-sibling::*[1]

如果您从用户输入中获取播放列表名称并且它们可能包含单引号或双引号字符,请小心。您没有说您使用的是什么库,但如果它支持定义变量,那么您应该使用该机制来注入您的值,而不是依赖字符串连接来构建您的表达式。

于 2013-07-31T16:22:46.253 回答