Nokogiri 用于阅读和编辑 Plist
Posted
技术标签:
【中文标题】Nokogiri 用于阅读和编辑 Plist【英文标题】:Nokogiri for reading and editing Plist 【发布时间】:2020-08-23 06:14:20 【问题描述】:我需要读取和编辑 plist 文件的一部分,它看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Bookstore</key>
<dict>
<key>Public</key>
<dict>
<key>Books</key>
<array>
<dict>
<key>Name</key>
<string>The Old Man and the Sea</string>
<key>Author</key>
<string>Hemingway</string>
</dict>
<dict>
<key>Name</key>
<string>A Brief History of Time</string>
<key>Author</key>
<string>Stephen Hawkin</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
到目前为止我做了什么:
require 'nokogiri'
doc = doc = Nokogiri::XML(File.open("books.plist"))
doc.xpath("//dict[key=\"Bookstore\"]/dict[key=\"Public\"]/dict[key=\"Books\"]")
如果我想获得 “Book”下元素的散列数组(在 Ruby 中),接下来我应该做什么?
谢谢!
【问题讨论】:
【参考方案1】:我认为您可以扩展您的选择以准确获取您需要的元素:
require 'nokogiri'
doc = Nokogiri::XML(File.open("books.plist"))
books = doc.xpath("//dict[key='Bookstore']/dict[key='Public']/dict[key='Books']/array/dict")
然后你可以通过子选择,或者遍历,将这组书本元素转换成你想要的形状,但是子选择可能看起来像这样:
final = books.map do |book|
keys = book.xpath("key/text()").map(&:to_s)
values = book.xpath("string/text()").map(&:to_s)
Hash[keys.zip(values)]
end
【讨论】:
谢谢,它有效!如果我更改任何值,比如书的 aurhor,我应该如何将其保存回原始 plist?【参考方案2】:你可以使用像plist_lite这样的Ruby gems
回答你的问题:
如果我想获取“Book”下元素的散列数组(在 Ruby 中),下一步该怎么做?
ruby -rplist_lite -e 'pp PlistLite.load($stdin.read)["Bookstore"]["Public"]["Books"]' <<EOS
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Bookstore</key>
<dict>
<key>Public</key>
<dict>
<key>Books</key>
<array>
<dict>
<key>Name</key>
<string>The Old Man and the Sea</string>
<key>Author</key>
<string>Hemingway</string>
</dict>
<dict>
<key>Name</key>
<string>A Brief History of Time</string>
<key>Author</key>
<string>Stephen Hawkin</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
EOS
输出
["Name"=>"The Old Man and the Sea", "Author"=>"Hemingway",
"Name"=>"A Brief History of Time", "Author"=>"Stephen Hawkin"]
如果你不想额外依赖,你仍然可以参考它的源代码,plist_lite
也使用nokogiri
进行解析:
https://github.com/tonytonyjan/plist_lite/blob/master/lib/plist_lite.rb#L37-L57
要更新 plist 文件,请使用 PlistLite#dump
:
obj = PlistLite.load(IO.read('test.plist'))
# modify obj...
IO.write('test.plist', PlistLite.dump(obj))
【讨论】:
以上是关于Nokogiri 用于阅读和编辑 Plist的主要内容,如果未能解决你的问题,请参考以下文章
创建“Nokogiri::XML”或“Nokogiri::HTML”对象时如何避免创建无意义的空白文本节点
在 OSX 10.10 Yosemite 上安装 Nokogiri
LoadError:库版本不兼容 - /home/ubuntu/.rvm/gems/ruby-2.3.1@lm5/gems/nokogiri-1.8.2/lib/nokogiri/nokogiri.s