== Parsing

  result = Plist::parse_xml('path/to/example.plist')

  result.class
  => Hash

  "#{result['FirstName']} #{result['LastName']}"
  => "John Public"

  result['ZipPostal']
  => "12345"

==== Example Property List

  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <dict>
          <key>FirstName</key>
          <string>John</string>

          <key>LastName</key>
          <string>Public</string>

          <key>StreetAddr1</key>
          <string>123 Anywhere St.</string>

          <key>StateProv</key>
          <string>CA</string>

          <key>City</key>
          <string>Some Town</string>

          <key>CountryName</key>
          <string>United States</string>

          <key>AreaCode</key>
          <string>555</string>

          <key>LocalPhoneNumber</key>
          <string>5551212</string>

          <key>ZipPostal</key>
          <string>12345</string>
  </dict>
  </plist>

== Generation

plist also provides the ability to generate plists from Ruby objects.  The following Ruby classes are converted into native plist types:
  Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false

* +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively).
* +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element.
* User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element.  See below for more details.

==== Creating a plist

There are two ways to generate complete plists.  Given an object:

  obj = [1, :two, {'c' => 0xd}]

If you've mixed in <tt>Plist::Emit</tt> (which is already done for +Array+ and +Hash+), you can simply call +to_plist+:

  obj.to_plist

This is equivalent to calling <tt>Plist::Emit.dump(obj)</tt>.  Either one will yield:

  <?xml version="1.0" encoding="UTF-8"?>
  <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
  <array>
      <integer>1</integer>
      <string>two</string>
      <dict>
        <key>c</key>
        <integer>13</integer>
      </dict>
  </array>
  </plist>

You can also dump plist fragments by passing +false+ as the second parameter:

  Plist::Emit.dump('holy cow!', false)
  => "<string>holy cow!</string>"

==== Custom serialization

If your class can be safely coerced into a native plist datatype, you can implement +to_plist_node+.  Upon encountering an object of a class it doesn't recognize, the plist library will check to see if it responds to +to_plist_node+, and if so, insert the result of that call into the plist output.

An example:

  class MyFancyString
    ...

    def to_plist_node
      return "<string>#{self.defancify}</string>"
    end
  end

When you attempt to serialize a +MyFancyString+ object, the +to_plist_node+ method will be called and the object's contents will be defancified and placed in the plist.

If for whatever reason you can't add this method, your object will be serialized with <tt>Marshal.dump</tt> instead.
