Find matching & non matching elements between 2 pl

2019-09-22 06:54发布

Find matching & non matching elements between 2 plist XML files, throughout the files?

I have 2 .plist XML filed from iOS; just an FYI.

  • What matters is figuring out which of items (Apps) exist in both files, and which ones do not.

  • Since, they could exist in various places, in any order, at any level of the XML structure, a simple File Compare using Beyond Compare etc. would not work.

I've done quite a bit of XML/ XSLT code back when XSLT 2.0 was being worked and Saxon was the only compliant parser. I have Altova XML Spy, DiffDog on Win 8.1.

But, I'm open to figuring out what's missing on both sides/ each side and what's there in both, using a non XML/ XSL mechanism as well, if it's easier.

  • Item Element is of this type: <string>com.apple.MobileSMS</string> and may exist at various places in the XML structure.

    • Exists as App under <array> to be counted for matching/ comparison
    • Can exist for Folder Names, under <dict> not to be counted for matching/ comparison
  • More details about this specific .plist XML structure is outlined here: http://iky1e.tumblr.com/post/11704062690/springboard-icon-layouts-iconstateplist

SpringBoard Icon Layouts - IconState.plist

I was looking for a way to get a list of all applications, that aren’t hidden (so excluding things like Web.app).
And although I found it ((NSArray*)[[SBIconModel sharedInstance] visibleIconIdentifiers]). I also found a dictionary SpringBoard keeps of the Icon layout.

Lets take a closer look at this:

  • the dock icons are in a separate array for key ‘buttonBar’;
  • the pages are in the array for key 'iconLists’;
  • each page is a separate array in the iconLists array;
  • in the array for each page the icons are string;
  • the icons string is the apps displayId;
  • a folder is an NSDictionary;
  • each folder has these keys;
    • a displayName key which is a string, it’s name;
    • iconLists which is an array of icons like each pages (displayId strings);

<!-- language-all: lang-xml -->

<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
 <all>
  <!-- Outer <dict> replaced by <all> -->
  <key>buttonBar</key>
  <array>
   <string>com.apple.MobileSMS</string>
   <string>com.apple.mobilemail</string>
   <string>com.apple.mobilesafari</string>
  </array>
  <key>iconLists</key>
  <pages>
   <!-- replaced by <pages> -->
   <page>
    <!-- replaced by <page> -->
    <string>com.apple.mobilephone</string>
    <string>com.apple.mobilecal</string>
    <string>com.apple.mobileslideshow</string>
    <string>com.apple.camera</string>
    <string>com.apple.videos</string>
    <string>com.apple.youtube</string>
    <string>com.apple.Maps</string>
    <string>com.apple.weather</string>
    <string>com.apple.mobilenotes</string>
    <string>com.apple.reminders</string>
    <string>com.apple.mobiletimer</string>
    <string>com.apple.gamecenter</string>
    <dict>
     <!-- Inner <dict> represents Folders -->
     <key>displayName</key>
     <string>Apple</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.apple.mobileme.fmf1</string>
       <string>com.apple.Cards</string>
       <string>com.apple.iBooks</string>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <string>com.apple.MobileStore</string>
    <string>com.apple.AppStore</string>
    <string>com.apple.Preferences</string>
   </page>
   <page>
    <dict>
     <key>displayName</key>
     <string>Utilities</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.apple.MobileAddressBook</string>
       <string>com.apple.calculator</string>
       <string>com.apple.VoiceMemos</string>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <dict>
     <key>displayName</key>
     <string>Jailbreak</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.saurik.Cydia</string>
       <string>libactivator</string>
       <string>eu.heinelt.ifile</string>
       <string>crash-reporter</string>
       <string>com.googlecode.mobileterminal.Terminal</string>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <dict>
     <key>displayName</key>
     <string>Social</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.atebits.Tweetie2</string>
       <string>info.colloquy.mobile</string>
       <string>com.tapbots.Tweetbot</string>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <dict>
     <key>displayName</key>
     <string>Other</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.apple.stocks</string>
       <dict>
        <key>displayName</key>
        <string>Newsstand</string>
        <key>iconLists</key>
        <array/>
        <key>listType</key>
        <string>newsstand</string>
       </dict>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <string>com.clickgamer.AngryBirds</string>
    <string>com.apple.mobileipod</string>
   </page>
   <page>
    <dict>
     <key>displayName</key>
     <string>Utilities</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.apple.MobileAddressBook</string>
       <string>com.apple.calculator</string>
       <string>com.apple.VoiceMemos</string>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <dict>
     <key>displayName</key>
     <string>Jailbreak</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.saurik.Cydia</string>
       <string>libactivator</string>
       <string>eu.heinelt.ifile</string>
       <string>crash-reporter</string>
       <string>com.googlecode.mobileterminal.Terminal</string>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <dict>
     <key>displayName</key>
     <string>Social</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.atebits.Tweetie2</string>
       <string>info.colloquy.mobile</string>
       <string>com.tapbots.Tweetbot</string>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <dict>
     <key>displayName</key>
     <string>Other</string>
     <key>iconLists</key>
     <array>
      <array>
       <string>com.apple.stocks</string>
       <dict>
        <key>displayName</key>
        <string>Newsstand</string>
        <key>iconLists</key>
        <array/>
        <key>listType</key>
        <string>newsstand</string>
       </dict>
      </array>
     </array>
     <key>listType</key>
     <string>folder</string>
    </dict>
    <string>com.clickgamer.AngryBirds</string>
    <string>com.apple.mobileipod</string>
   </page>
  </pages>
 </all>
</plist>

标签: xml xslt match
1条回答
叛逆
2楼-- · 2019-09-22 07:37

Given your comments, it sounds like you need a table listing all the unique string values that are children of array elements and that appear in both files, including also a list of values unique to the first file and those unique to the second file.

Assuming you've loaded the two files into variables called File1 and File2, you could generate the main full list using an XPath expression like:

distinct-values($File1//array/string | $File2//array/string)

To test for values unique to File1, where the context item . is one of the values in the main full list:

<xsl:if test=". = $File1//array/string and not(. = $File2//array/string)">

... and for values unique to File2:

<xsl:if test=". = $File2//array/string and not(. = $File1//array/string)">

This approach could be further refined, such as by sorting the list. The above addresses the core of your needs. From there, you can decide how you want to lay out the values, be it in an HTML table or some other structure.

查看更多
登录 后发表回答