Search code examples
phpxmlsimplexml

Can you use SimpleXML in PHP to parse plist files?


I have always used PHP's SimpleXML to parse XML files, but I am now facing a challenge trying to parse a plist file.

An example taken from the Apple Mac Developer Library:

<?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>Year Of Birth</key>
           <integer>1965</integer>
           <key>Pets Names</key>
           <array/>
           <key>Picture</key>
           <data>
               PEKBpYGlmYFCPA==
           </data>
           <key>City of Birth</key>
           <string>Springfield</string>
           <key>Name</key>
           <string>John Doe</string>
           <key>Kids Names</key>
           <array>
               <string>John</string>
               <string>Kyra</string>
           </array>
       </dict>
       </plist>

In a case like this, things are easy enough: if I wanted, for example, to get the year of birth, I would just do $xml -> dict -> integer since there is only one integer in this list.

However, how can I return the value of a field using its key name (like select the integer with key Year of Birth)?

I could just use the order of elements but I am ideally looking for a solution that would continue working if the elements get rearranged in the XML file in the future.


Solution

  • The following XPath would do that for you:

    /plist/dict/key[text()="Year Of Birth"]/following-sibling::*[1]
    

    With SimpleXml

    $plist = simplexml_load_string($xml);
    $query = '/plist/dict/key[text()="Year Of Birth"]/following-sibling::*[1]';       
    $results = $plist->xpath($query);
    echo (string) $results[0]; // 1965