Nokogiri:解析和更新Plist中的值

问题描述

我是Ruby的新手,需要处理一家书店的plist,比如说我有一个plist,

<plist>
<array>
<dict>
  <key>Name</key>
  <string>An Old Man and the Sea</string>
  <key>Available</key>
  <true/>
</dict>
<dict>
  <key>Name</key>
  <string>The Hitchhiker's Guide To galaxy</string>
  <key>Available</key>
  <false/>
</dict>
</array>
</plist>

我需要切换书籍的可用性,并且我已经阅读了plist并将书籍阵列解析为books

books.map do |book|
  book.xpath("key/text()") # e.g. ["Name","Available"]
  book.xpath("string/text()") # e.g. ["An Old Man and the Sea"]
end

问题:

  1. 如何读取值<true/><false/>
  2. 如何更新值并保存plist?

谢谢!

解决方法

如果您不介意使用 gem,则可以使用 plist_lite

ruby -r plist_lite -e 'p PlistLite.load($stdin.read)' <<EOS
<plist>
<array>
<dict>
  <key>Name</key>
  <string>An Old Man and the Sea</string>
  <key>Available</key>
  <true/>
</dict>
<dict>
  <key>Name</key>
  <string>The Hitchhiker's Guide To Galaxy</string>
  <key>Available</key>
  <false/>
</dict>
</array>
</plist>
EOS

输出:

[{"Name"=>"An Old Man and the Sea","Available"=>true},{"Name"=>"The Hitchhiker's Guide To Galaxy","Available"=>false}]

如果你想自己用nokogiri来做,可以参考这里plist_lite的源代码,它也用了nokogiri

https://github.com/tonytonyjan/plist_lite/blob/2de0506/lib/plist_lite.rb#L37-L57

回答您的问题:

如何读取值 <true/><false/>

parsed = PlistLite.load(plist_string)
parsed.map{ _1['Available'] }

如何更新值并保存 plist?

parsed = PlistLite.load(plist_string)
parsed.first['Available']
IO.write 'test.plist',PlistLite.dump(parsed)