ruby - 带有 dict 元素的 Plist XPath 查询

标签 ruby xml xpath nokogiri

我正在尝试通过 Nokigiri 从 plist 的 iTunes 库导出中加载歌曲名称:

doc = Nokogiri::XML(打开(文件.路径))

@songs = Array.new  
doc.xpath(<XPATH_HERE>).each do |n|
  @songs.push(n)  #append data to array
end 

plist 的开头如下所示:

<plist version="1.0">
<dict>
  <key>Major Version</key><integer>1</integer>
  <key>Minor Version</key><integer>1</integer>
  <key>Date</key><date>2014-10-15T22:52:19Z</date>
  <key>Application Version</key><string>11.4</string>
  <key>Features</key><integer>5</integer>
  <key>Show Content Ratings</key><true/>
  <key>Music Folder</key><string>file://localhost/Users/mike/Music/iTunes/iTunes%20Media/</string>
  <key>Library Persistent ID</key><string>280B84572DDCF406</string>
  <key>Tracks</key>
  <dict>
    <key>96</key>
    <dict>
      <key>Track ID</key><integer>96</integer>
      <key>Name</key><string>Get Lucky (Daft Punk cover)</string>
      <key>Artist</key><string>Daughter</string>
      <key>Kind</key><string>MPEG audio file</string>
      <key>Size</key><integer>4716638</integer>
      <key>Total Time</key><integer>294112</integer>
      <key>Date Modified</key><date>2013-11-12T20:54:14Z</date>
      <key>Date Added</key><date>2013-12-18T17:56:09Z</date>
      <key>Bit Rate</key><integer>128</integer>
      <key>Sample Rate</key><integer>44100</integer>
      <key>Persistent ID</key><string>C3B1B6F26134C9C1</string>
      <key>Track Type</key><string>File</string>
      <key>Location</key><string>file://localhost/Users/mike/Music/iTunes/iTunes%20Media/Music/Daughter/Unknown%20Album/Get%20Lucky%20(Daft%20Punk%20cover).mp3</string>
      <key>File Folder Count</key><integer>5</integer>
      <key>Library Folder Count</key><integer>1</integer>
    </dict>
    <key>98</key>
    <dict>
      <key>Track ID</key><integer>98</integer>
      <key>Name</key><string>Swimming in Solace (DJ Fergie Ferg Remash)</string>
      <key>Kind</key><string>MPEG audio file</string>

我希望从每个轨道加载的是名称键后面的轨道名称字符串。我认为应该工作的 XPath 是

/plist/dict[key[. = 'Tracks']/following-sibling::*[1]]/dict[key/following-sibling::*[1]]/dict[key[. = 'Name']/following-sibling::*[1]]/string

XPath 返回:

<string>Get Lucky (Daft Punk cover)</string>
<string>Daughter</string>
<string>MPEG audio file</string>
<string>C3B1B6F26134C9C1</string>
<string>File</string>
<string>file://localhost/Users/mike/Music/iTunes/iTunes%20Media/Music/Daughter/Unknown%20Album/Get%20Lucky%20(Daft%20Punk%20cover).mp3</string>
<string>Swimming in Solace (DJ Fergie Ferg Remash)</string>
<string>MPEG audio file</string>

看起来,虽然我的 XPath 指定了每个字符串的键,但实际上它不管如何都采用了所有字典的“following-siblings”。

我该怎么做才能使查询更具体,以便 plist 的这一部分返回:

Get Lucky (Daft Punk cover)

Swimming in Solace (DJ Fergie Ferg Remash)

最佳答案

这是一种可能的 XPath:

/plist/dict[key='Tracks']/dict/dict/key[.='Name']/following-sibling::string[1]

XPath 的开头可能会有所不同,但我认为最重要的部分是最后两个路径步骤 ( key[.='Name']/following-sibling::string[1] )。它告诉我们获得最近的 <string>每个 <key>Name</key> 之后的元素元素。

关于ruby - 带有 dict 元素的 Plist XPath 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26419768/

相关文章:

xml - 修改 Groovy 中现有的 xml 文件

xpath - XQuery 使用什么表达式来计算匹配字符串的数量?

extjs - 如何使用 ExtJS 为页面上的元素找到唯一的选择器以与 Selenium 一起使用?

Ruby - 从另一个方法中提取我的较小方法(将字符串转换为两个数字和一个符号)

ruby - 事件记录范围 : Strange behaviour with select on relation

java - 如何使 photoview 库与 viewpager 一起工作

xml - 在 Hive 上使用 XPATH 获取 XML 节点的名称

ruby-on-rails - ActionMailer 渲染一次,发送多次?

ruby-on-rails - `can' t 修改卡住数组 (RuntimeError)` 试图更新到 Rails 5.1

c# - XML 的 Saml2Assertion 为空