class CFPropertyList::XML

XML parser

def append_node(parent, child)

def append_node(parent, child)
  parent << child
end

def append_node(parent, child)

def append_node(parent, child)
  parent << child
end

def append_node(parent, child)

def append_node(parent, child)
  if child.is_a?(String) then
    parent.add_text child
  else
    parent.elements << child
  end
  parent
end

def get_value(n)

get the value of a DOM node
def get_value(n)
  content = if n.children?
    n.first.content
  else
    n.content
  end
  content.force_encoding('UTF-8') if content.respond_to?(:force_encoding)
  content
end

def get_value(n)

get the value of a DOM node
def get_value(n)
  content = if n.children.empty?
    n.content
  else
    n.children.first.content
  end
  content.force_encoding('UTF-8') if content.respond_to?(:force_encoding)
  content
end

def get_value(n)

get the value of a DOM node
def get_value(n)
  content = n.text
  content.force_encoding('UTF-8') if content.respond_to?(:force_encoding)
  content
end

def import_xml(node)

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|
        next if n.text? # avoid a bug of libxml
        next if n.comment?
        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

def import_xml(node)

import the XML values
def import_xml(node)
  ret = nil
  case node.name
  when 'dict'
    hsh = Hash.new
    key = nil
    children = node.children
    unless children.empty? then
      children.each do |n|
        next if n.text? # avoid a bug of libxml
        next if n.comment?
        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
    children = node.children
    unless children.empty? then
      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

def import_xml(node)

import the XML values
def import_xml(node)
  ret = nil
  case node.name
  when 'dict'
    hsh = Hash.new
    key = nil
    if node.has_elements? then
      node.elements.each do |n|
        #print n.name + "\n"
        next if n.name == '#text' # avoid a bug of libxml
        next if n.name == '#comment'
        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.has_elements? then
      node.elements.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

def load(opts)

* :data - The data to parse
* :file - The filename of the file to load
opts::
read a XML file
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

def load(opts)

* :data - The data to parse
* :file - The filename of the file to load
opts::
read a XML file
def load(opts)
  doc = nil
  if(opts.has_key?(:file)) then
    File.open(opts[:file], "rb") { |fd| doc = Nokogiri::XML::Document.parse(fd, nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS|Nokogiri::XML::ParseOptions::NOENT) }
  else
    doc = Nokogiri::XML::Document.parse(opts[:data], nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS|Nokogiri::XML::ParseOptions::NOENT)
  end
  root = doc.root.children.first
  return import_xml(root)
end

def load(opts)

* :data - The data to parse
* :file - The filename of the file to load
opts::
read a XML file
def load(opts)
  doc = nil
  if(opts.has_key?(:file)) then
    File.open(opts[:file], "rb") { |fd| doc = REXML::Document.new(fd) }
  else
    doc = REXML::Document.new(opts[:data])
  end
  root = doc.root.elements[1]
  return import_xml(root)
end

def new_node(name)

def new_node(name)
  LibXML::XML::Node.new(name)
end

def new_node(name)

def new_node(name)
  @doc.create_element name
end

def new_node(name)

def new_node(name)
  #LibXML::XML::Node.new(name)
  REXML::Element.new(name)
end

def new_text(val)

def new_text(val)
  LibXML::XML::Node.new_text(val)
end

def new_text(val)

def new_text(val)
  @doc.create_text_node val
end

def new_text(val)

def new_text(val)
  val
end

def to_str(opts={})

opts = {}:: Specify options: :formatted - Use indention and line breaks
serialize CFPropertyList object to XML
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(self)
  # 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//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" if line =~ /^\s*<\?xml/
    end
    first = true
  end
  str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
  return str1
end

def to_str(opts={})

opts = {}:: Specify options: :formatted - Use indention and line breaks
serialize CFPropertyList object to XML
def to_str(opts={})
  doc = Nokogiri::XML::Document.new
  @doc = doc
  doc.root = doc.create_element 'plist', :version => '1.0'
  doc.encoding = 'UTF-8'
  doc.root << opts[:root].to_xml(self)
  # ugly hack, but there's no other possibility I know
  s_opts = Nokogiri::XML::Node::SaveOptions::AS_XML
  s_opts |= Nokogiri::XML::Node::SaveOptions::FORMAT if opts[:formatted]
  str = doc.serialize(:save_with => s_opts)
  str1 = String.new
  first = false
  str.each_line do |line|
    str1 << line
    unless(first) then
      str1 << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" if line =~ /^\s*<\?xml/
    end
    first = true
  end
  str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
  return str1
end

def to_str(opts={})

opts = {}:: Specify options: :formatted - Use indention and line breaks
serialize CFPropertyList object to XML
def to_str(opts={})
  doc = REXML::Document.new
  @doc = doc
  doc.context[:attribute_quote] = :quote
  doc.add_element 'plist', {'version' => '1.0'}
  doc.root << opts[:root].to_xml(self)
  formatter = if opts[:formatted] then
    f = REXML::Formatters::Pretty.new(2)
    f.compact = true
    f
  else
    REXML::Formatters::Default.new
  end
  str = formatter.write(doc.root, "")
  str1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" + str + "\n"
  str1.force_encoding('UTF-8') if str1.respond_to?(:force_encoding)
  return str1
end