121 lines
3.1 KiB
Ruby
121 lines
3.1 KiB
Ruby
# -*- coding: utf-8 -*-
|
|
# CFPropertyList implementation
|
|
# parser class to read, manipulate and write XML property list files (plist(5)) as defined by Apple
|
|
#
|
|
# Author:: Christian Kruse (mailto:cjk@wwwtech.de)
|
|
# Copyright:: Copyright (c) 2010
|
|
# License:: Distributes under the same terms as Ruby
|
|
|
|
module CFPropertyList
|
|
# XML parser
|
|
class XML < ParserInterface
|
|
# read a XML file
|
|
# opts::
|
|
# * :file - The filename of the file to load
|
|
# * :data - The data to parse
|
|
def load(opts)
|
|
if(opts.has_key?(:file)) then
|
|
doc = LibXML::XML::Document.file(opts[:file],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
|
|
else
|
|
doc = LibXML::XML::Document.string(opts[:data],:options => LibXML::XML::Parser::Options::NOBLANKS|LibXML::XML::Parser::Options::NOENT)
|
|
end
|
|
|
|
root = doc.root.first
|
|
return import_xml(root)
|
|
end
|
|
|
|
# serialize CFPropertyList object to XML
|
|
# opts = {}:: Specify options: :formatted - Use indention and line breaks
|
|
def to_str(opts={})
|
|
doc = LibXML::XML::Document.new
|
|
|
|
doc.root = LibXML::XML::Node.new('plist')
|
|
doc.encoding = LibXML::XML::Encoding::UTF_8
|
|
|
|
doc.root['version'] = '1.0'
|
|
doc.root << opts[:root].to_xml()
|
|
|
|
# ugly hack, but there's no other possibility I know
|
|
str = doc.to_s(:indent => opts[:formatted])
|
|
str1 = String.new
|
|
first = false
|
|
str.each_line do
|
|
|line|
|
|
str1 << line
|
|
unless(first) then
|
|
str1 << "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" if line =~ /^\s*<\?xml/
|
|
end
|
|
|
|
first = true
|
|
end
|
|
|
|
return str1
|
|
end
|
|
|
|
protected
|
|
|
|
# get the value of a DOM node
|
|
def get_value(n)
|
|
return n.first.content if n.children?
|
|
return n.content
|
|
end
|
|
|
|
# import the XML values
|
|
def import_xml(node)
|
|
ret = nil
|
|
|
|
case node.name
|
|
when 'dict'
|
|
hsh = Hash.new
|
|
key = nil
|
|
|
|
if node.children? then
|
|
node.children.each do
|
|
|n|
|
|
|
|
if n.name == "key" then
|
|
key = get_value(n)
|
|
else
|
|
raise CFFormatError.new("Format error!") if key.nil?
|
|
hsh[key] = import_xml(n)
|
|
key = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
ret = CFDictionary.new(hsh)
|
|
|
|
when 'array'
|
|
ary = Array.new
|
|
|
|
if node.children? then
|
|
node.children.each do
|
|
|n|
|
|
ary.push import_xml(n)
|
|
end
|
|
end
|
|
|
|
ret = CFArray.new(ary)
|
|
|
|
when 'true'
|
|
ret = CFBoolean.new(true)
|
|
when 'false'
|
|
ret = CFBoolean.new(false)
|
|
when 'real'
|
|
ret = CFReal.new(get_value(node).to_f)
|
|
when 'integer'
|
|
ret = CFInteger.new(get_value(node).to_i)
|
|
when 'string'
|
|
ret = CFString.new(get_value(node))
|
|
when 'data'
|
|
ret = CFData.new(get_value(node))
|
|
when 'date'
|
|
ret = CFDate.new(CFDate.parse_date(get_value(node)))
|
|
end
|
|
|
|
return ret
|
|
end
|
|
end
|
|
end
|
|
|
|
# eof
|