Search code examples
pythonplist

read plist files in non-XML format using python


I am reading MacOS data that is in plist (propertly list) format that is not in the XML format, not in the binary format, but in the other ascii format. For example:

addr= {
    City = "San Francisco Bay Area";
}

I am trying to parse this into a Python dictionary. Unfortunately, plistlib.loads returns InvalidFileException() when I try to parse it:

import plistlib

plist=b"""
addr= {
    City = "San Francisco Bay Area";
}
"""

print( plistlib.loads( plist ) )

Produces:

Traceback (most recent call last):
  File "x.py", line 9, in <module>
    print( plistlib.loads( plist ) )
  File "/Users/simsong/anaconda/lib/python3.6/plistlib.py", line 1024, in loads
    fp, fmt=fmt, use_builtin_types=use_builtin_types, dict_type=dict_type)
  File "/Users/simsong/anaconda/lib/python3.6/plistlib.py", line 1009, in load
    raise InvalidFileException()
plistlib.InvalidFileException: Invalid file

What's the correct way to do this?


Solution

  • You are talking about plist files in the JSON format. Your example is not JSON.

    Let's start with this sample plist in XML

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
    <plist version="1.0">
    <dict>
        <key>Author</key>
        <string>William Shakespeare</string>
        <key>Lines</key>
        <array>
            <string>It is a tale told by an idiot,</string>
            <string>Full of sound and fury, signifying nothing.</string>
        </array>
        <key>Birthdate</key>
        <integer>1564</integer>
    </dict>
    </plist>
    

    And convert it to JSON format:

    plutil -convert json sample.plist 
    
    {"Author":"William Shakespeare","Birthdate":1564,"Lines":["It is a tale told by an idiot,","Full of sound and fury, signifying nothing."]}
    

    Now you can read this using the JSON library.

    import json
    
    plist_text = '{"Author":"William Shakespeare","Birthdate":1564,"Lines":["It is a tale told by an idiot,","Full of sound and fury, signifying nothing."]}'
    
    plist = json.loads(plist_text)
    
    print('The author is ' + plist['Author'])
    

    Output:

    $ python3 plist.py 
    $ The author is William Shakespeare