NSKeyedUnarchiver, ASObjc - Not retrieving Values from a NSKeyedArchiver File

Hi,

im working on a script to parse values from a given XML File.
I know the File was saved using the NSKeyedArchiver Object, but using the NSKeyedUnarchiver Methode >>"unarchiver’s decodeObjectForKey:“FAT_ImportoRitenuta”<< as described in @ShaneStanley Book (thanks for this great Book) i get “missing value”.

Here the XML-File as whole:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>$archiver</key>
	<string>FSKeyedArchiver</string>
	<key>$objects</key>
	<array>
		<string>$null</string>
		<dict>
			<key>$class</key>
			<dict>
				<key>CF$UID</key>
				<integer>79</integer>
			</dict>
			<key>NS.key.0</key>
			<dict>
				<key>CF$UID</key>
				<integer>2</integer>
			</dict>
			<key>NS.key.1</key>
			<dict>
				<key>CF$UID</key>
				<integer>4</integer>
			</dict>
			<key>NS.key.10</key>
			<dict>
				<key>CF$UID</key>
				<integer>29</integer>
			</dict>
			<key>NS.key.11</key>
			<dict>
				<key>CF$UID</key>
				<integer>31</integer>
			</dict>
			<key>NS.key.12</key>
			<dict>
				<key>CF$UID</key>
				<integer>33</integer>
			</dict>
			<key>NS.key.13</key>
			<dict>
				<key>CF$UID</key>
				<integer>35</integer>
			</dict>
			<key>NS.key.14</key>
			<dict>
				<key>CF$UID</key>
				<integer>37</integer>
			</dict>
			<key>NS.key.15</key>
			<dict>
				<key>CF$UID</key>
				<integer>39</integer>
			</dict>
			<key>NS.key.16</key>
			<dict>
				<key>CF$UID</key>
				<integer>41</integer>
			</dict>
			<key>NS.key.17</key>
			<dict>
				<key>CF$UID</key>
				<integer>43</integer>
			</dict>
			<key>NS.key.18</key>
			<dict>
				<key>CF$UID</key>
				<integer>44</integer>
			</dict>
			<key>NS.key.19</key>
			<dict>
				<key>CF$UID</key>
				<integer>46</integer>
			</dict>
			<key>NS.key.2</key>
			<dict>
				<key>CF$UID</key>
				<integer>6</integer>
			</dict>
			<key>NS.key.20</key>
			<dict>
				<key>CF$UID</key>
				<integer>47</integer>
			</dict>
			<key>NS.key.21</key>
			<dict>
				<key>CF$UID</key>
				<integer>49</integer>
			</dict>
			<key>NS.key.22</key>
			<dict>
				<key>CF$UID</key>
				<integer>51</integer>
			</dict>
			<key>NS.key.23</key>
			<dict>
				<key>CF$UID</key>
				<integer>53</integer>
			</dict>
			<key>NS.key.24</key>
			<dict>
				<key>CF$UID</key>
				<integer>55</integer>
			</dict>
			<key>NS.key.25</key>
			<dict>
				<key>CF$UID</key>
				<integer>57</integer>
			</dict>
			<key>NS.key.26</key>
			<dict>
				<key>CF$UID</key>
				<integer>59</integer>
			</dict>
			<key>NS.key.27</key>
			<dict>
				<key>CF$UID</key>
				<integer>61</integer>
			</dict>
			<key>NS.key.28</key>
			<dict>
				<key>CF$UID</key>
				<integer>63</integer>
			</dict>
			<key>NS.key.29</key>
			<dict>
				<key>CF$UID</key>
				<integer>65</integer>
			</dict>
			<key>NS.key.3</key>
			<dict>
				<key>CF$UID</key>
				<integer>8</integer>
			</dict>
			<key>NS.key.30</key>
			<dict>
				<key>CF$UID</key>
				<integer>67</integer>
			</dict>
			<key>NS.key.31</key>
			<dict>
				<key>CF$UID</key>
				<integer>69</integer>
			</dict>
			<key>NS.key.32</key>
			<dict>
				<key>CF$UID</key>
				<integer>71</integer>
			</dict>
			<key>NS.key.33</key>
			<dict>
				<key>CF$UID</key>
				<integer>73</integer>
			</dict>
			<key>NS.key.34</key>
			<dict>
				<key>CF$UID</key>
				<integer>75</integer>
			</dict>
			<key>NS.key.35</key>
			<dict>
				<key>CF$UID</key>
				<integer>77</integer>
			</dict>
			<key>NS.key.4</key>
			<dict>
				<key>CF$UID</key>
				<integer>10</integer>
			</dict>
			<key>NS.key.5</key>
			<dict>
				<key>CF$UID</key>
				<integer>12</integer>
			</dict>
			<key>NS.key.6</key>
			<dict>
				<key>CF$UID</key>
				<integer>14</integer>
			</dict>
			<key>NS.key.7</key>
			<dict>
				<key>CF$UID</key>
				<integer>16</integer>
			</dict>
			<key>NS.key.8</key>
			<dict>
				<key>CF$UID</key>
				<integer>18</integer>
			</dict>
			<key>NS.key.9</key>
			<dict>
				<key>CF$UID</key>
				<integer>20</integer>
			</dict>
			<key>NS.object.0</key>
			<dict>
				<key>CF$UID</key>
				<integer>3</integer>
			</dict>
			<key>NS.object.1</key>
			<dict>
				<key>CF$UID</key>
				<integer>5</integer>
			</dict>
			<key>NS.object.10</key>
			<dict>
				<key>CF$UID</key>
				<integer>30</integer>
			</dict>
			<key>NS.object.11</key>
			<dict>
				<key>CF$UID</key>
				<integer>32</integer>
			</dict>
			<key>NS.object.12</key>
			<dict>
				<key>CF$UID</key>
				<integer>34</integer>
			</dict>
			<key>NS.object.13</key>
			<dict>
				<key>CF$UID</key>
				<integer>36</integer>
			</dict>
			<key>NS.object.14</key>
			<dict>
				<key>CF$UID</key>
				<integer>38</integer>
			</dict>
			<key>NS.object.15</key>
			<dict>
				<key>CF$UID</key>
				<integer>40</integer>
			</dict>
			<key>NS.object.16</key>
			<dict>
				<key>CF$UID</key>
				<integer>42</integer>
			</dict>
			<key>NS.object.17</key>
			<dict>
				<key>CF$UID</key>
				<integer>21</integer>
			</dict>
			<key>NS.object.18</key>
			<dict>
				<key>CF$UID</key>
				<integer>45</integer>
			</dict>
			<key>NS.object.19</key>
			<dict>
				<key>CF$UID</key>
				<integer>5</integer>
			</dict>
			<key>NS.object.2</key>
			<dict>
				<key>CF$UID</key>
				<integer>7</integer>
			</dict>
			<key>NS.object.20</key>
			<dict>
				<key>CF$UID</key>
				<integer>48</integer>
			</dict>
			<key>NS.object.21</key>
			<dict>
				<key>CF$UID</key>
				<integer>50</integer>
			</dict>
			<key>NS.object.22</key>
			<dict>
				<key>CF$UID</key>
				<integer>52</integer>
			</dict>
			<key>NS.object.23</key>
			<dict>
				<key>CF$UID</key>
				<integer>54</integer>
			</dict>
			<key>NS.object.24</key>
			<dict>
				<key>CF$UID</key>
				<integer>56</integer>
			</dict>
			<key>NS.object.25</key>
			<dict>
				<key>CF$UID</key>
				<integer>58</integer>
			</dict>
			<key>NS.object.26</key>
			<dict>
				<key>CF$UID</key>
				<integer>60</integer>
			</dict>
			<key>NS.object.27</key>
			<dict>
				<key>CF$UID</key>
				<integer>62</integer>
			</dict>
			<key>NS.object.28</key>
			<dict>
				<key>CF$UID</key>
				<integer>64</integer>
			</dict>
			<key>NS.object.29</key>
			<dict>
				<key>CF$UID</key>
				<integer>66</integer>
			</dict>
			<key>NS.object.3</key>
			<dict>
				<key>CF$UID</key>
				<integer>9</integer>
			</dict>
			<key>NS.object.30</key>
			<dict>
				<key>CF$UID</key>
				<integer>68</integer>
			</dict>
			<key>NS.object.31</key>
			<dict>
				<key>CF$UID</key>
				<integer>70</integer>
			</dict>
			<key>NS.object.32</key>
			<dict>
				<key>CF$UID</key>
				<integer>72</integer>
			</dict>
			<key>NS.object.33</key>
			<dict>
				<key>CF$UID</key>
				<integer>74</integer>
			</dict>
			<key>NS.object.34</key>
			<dict>
				<key>CF$UID</key>
				<integer>76</integer>
			</dict>
			<key>NS.object.35</key>
			<dict>
				<key>CF$UID</key>
				<integer>78</integer>
			</dict>
			<key>NS.object.4</key>
			<dict>
				<key>CF$UID</key>
				<integer>11</integer>
			</dict>
			<key>NS.object.5</key>
			<dict>
				<key>CF$UID</key>
				<integer>13</integer>
			</dict>
			<key>NS.object.6</key>
			<dict>
				<key>CF$UID</key>
				<integer>15</integer>
			</dict>
			<key>NS.object.7</key>
			<dict>
				<key>CF$UID</key>
				<integer>17</integer>
			</dict>
			<key>NS.object.8</key>
			<dict>
				<key>CF$UID</key>
				<integer>19</integer>
			</dict>
			<key>NS.object.9</key>
			<dict>
				<key>CF$UID</key>
				<integer>21</integer>
			</dict>
		</dict>
		<string>FAT_ImportoRitenuta</string>
		<string>54.05</string>
		<string>CLIE_PIVA</string>
		<string>0101010</string>
		<string>FAT_PrezzoTotaleLinea</string>
		<string>470</string>
		<string>FAT_DetrazioneLinea</string>
		<string>FAT_PH_DetrazioneLinea</string>
		<string>EMI_CodFisc</string>
		<string>MCHBNN74C20A952B</string>
		<string>FAT_NaturaLinea</string>
		<string>Kronsbühl Copy</string>
		<string>FAT_QuantitaLinea</string>
		<string>1</string>
		<string>EMI_CAPeCitta</string>
		<string>St. Ulrich 39036 Italien</string>
		<string>EMI_RagioneSociale</string>
		<string>Benno Micheler</string>
		<string>FAT_DataREG</string>
		<dict>
			<key>$class</key>
			<dict>
				<key>CF$UID</key>
				<integer>28</integer>
			</dict>
			<key>NS.format</key>
			<dict>
				<key>CF$UID</key>
				<integer>27</integer>
			</dict>
			<key>NS.time</key>
			<real>585644852.48439395</real>
			<key>NS.timezone</key>
			<dict>
				<key>CF$UID</key>
				<integer>22</integer>
			</dict>
		</dict>
		<dict>
			<key>$class</key>
			<dict>
				<key>CF$UID</key>
				<integer>26</integer>
			</dict>
			<key>NS.data</key>
			<dict>
				<key>CF$UID</key>
				<integer>24</integer>
			</dict>
			<key>NS.name</key>
			<dict>
				<key>CF$UID</key>
				<integer>23</integer>
			</dict>
		</dict>
		<string>Europe/Rome</string>
		<dict>
			<key>$class</key>
			<dict>
				<key>CF$UID</key>
				<integer>25</integer>
			</dict>
			<key>NS.bytes</key>
			<data>
			VFppZgAAAAAAAAAAAAAAAAAAAAAAAAAGAAAABgAAAAAAAACqAAAA
			BgAAAAmbN6bwm9Xa8JzFy/Cdtbzwnon+cJ+e2XCgYKXwoX67cKJc
			N3CjTChwyGw18MznSxDNqReQzqJDEM+SNBDQB19g0G5CcNFyFhDS
			TNLw0z4xkNRJ0hDVHfdw1imX8NbrgJDYCZYQ+TO18PnZxOD7HNJw
			+7mm4Pz8tHD9mYjg/uXQ8P+CpWAAxbLwAWKHYAKcWnADQndwBIV2
			8AUrheAGbpNwBwtn4AhFOvAI60ngCi5XcArLOfAMDjlwDKsb8A3k
			4PAOiv3wD839cBB0GnARrd9wElP8cBLOl/ATTUQQFDP6kBUj65AW
			E9yQFwPNkBfzvpAY46+QGdOgkBrDkZAbvL0QHKyuEB2cnxAejJAQ
			H3yBECBschAhXGMQIkxUECM8RRAkLDYQJRwnECYMGBAnBUOQJ/U0
			kCjlJZAp1RaQKsUHkCu0+JAspOmQLZTakC6Ey5AvdLyQMGStkDFd
			2RAycrQQMz27EDRSlhA1HZ0QNjJ4EDb9fxA4G5SQON1hEDn7dpA6
			vUMQO9tYkDymX5A9uzqQPoZBkD+bHJBAZiOQQYQ5EEJGBZBDZBsQ
			RCXnkEVD/RBGBcmQRyPfEEfu5hBJA8EQSc7IEErjoxBLrqoQTMy/
			kE2OjBBOrKGQT25uEFCMg5BRV4qQUmxlkFM3bJBUTEeQVRdOkFYs
			KZBW9zCQWBVGEFjXEpBZ9SgQWrb0kFvVChBcoBEQXbTsEF5/8xBf
			lM4QYF/VEGF96pBiP7cQY13MkGQfmRBlPa6QZgi1kGcdkJBn6JeQ
			aP1ykGnIeZBq3VSQa6hbkGzGcRBtiD2QbqZTEG9oH5BwhjUQcVE8
			EHJmFxBzMR4QdEX5EHURABB2LxWQdvDiEHgO95B40MQQee7ZkHqw
			phB7zruQfJnCkH2unZB+eaSQf45/kAABAAEAAQABAAEAAQABAAIB
			AgEAAQABAAECAwIDAgMCAwIDAgMCAwIDAgMAAQABAAEAAQABAwQF
			BAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUE
			BQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQF
			BAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFBAUEBQQFAAAc
			IAEAAAAOEAAFAAAcIAEAAAAOEAAFAAAcIAEAAAAOEAAFQ0VTVABD
			RVQAAQEAAAEBAAAAAAEB
			</data>
		</dict>
		<dict>
			<key>$classes</key>
			<array>
				<string>NSMutableData</string>
				<string>NSData</string>
				<string>NSObject</string>
			</array>
			<key>$classname</key>
			<string>NSMutableData</string>
		</dict>
		<dict>
			<key>$classes</key>
			<array>
				<string>NSTimeZone</string>
				<string>NSObject</string>
			</array>
			<key>$classname</key>
			<string>NSTimeZone</string>
		</dict>
		<string>%Y-%m-%d %H:%M:%S %z</string>
		<dict>
			<key>$classes</key>
			<array>
				<string>NSCalendarDate</string>
				<string>NSDate</string>
				<string>NSObject</string>
			</array>
			<key>$classname</key>
			<string>NSCalendarDate</string>
		</dict>
		<string>FAT_Ritenuta</string>
		<string>SI</string>
		<string>FAT_AliquotaIVA</string>
		<string>0.21</string>
		<string>CLIE_STRADAeNr</string>
		<string>RIENZFELDSTRASSE 30</string>
		<string>FAT_RiferimentoNumeroEnasarco</string>
		<string>-1.907348625707073e-07</string>
		<string>EMI_Nazione</string>
		<string>IT</string>
		<string>FAT_RiferimentoTestoEnasarco</string>
		<string>TC07 - ENASARCO (8,25)</string>
		<string>CLIE_CodiceDestinatario</string>
		<string>CLIE_PH_CodiceDestinatario</string>
		<string>FAT_Data</string>
		<string>FAT_ImportoTotaleDocumento</string>
		<string>514.6500001907349</string>
		<string>CLIE_CodFisc</string>
		<string>EMI_PIVA</string>
		<string>IT02555480215</string>
		<string>FAT_Tipo</string>
		<string>FPR12</string>
		<string>EMI_STRADAeNr</string>
		<string>via Sacun 7</string>
		<string>FAT_NumeroLinea</string>
		<string>3</string>
		<string>FAT_Nr</string>
		<string>317</string>
		<string>CLIE_Nazione</string>
		<string>Italien</string>
		<string>CLIE_CAPeCitta</string>
		<string>39031 BRUNECK</string>
		<string>FAT_TipoRitenuta</string>
		<string>RT01</string>
		<string>FAT_DeducibileLinea</string>
		<string>FAT_PH_DeducibileLinea</string>
		<string>FAT_PrezzoUnitarioLinea</string>
		<string>470</string>
		<string>FAT_ImpostaIVA</string>
		<string>98.7</string>
		<string>FAT_CausalePagamentoRitenuta</string>
		<string>R</string>
		<string>FAT_ImponibileImportoIVA</string>
		<string>470</string>
		<string>FAT_TipoDatoEnasarco</string>
		<string>CASSA PREV</string>
		<string>FAT_AliquotaRitenuta</string>
		<string>23</string>
		<string>CLIE_RagioneSociale</string>
		<string>INC_ Bruneck INC_ BRUNECK</string>
		<dict>
			<key>$classes</key>
			<array>
				<string>NSMutableDictionary</string>
				<string>NSDictionary</string>
				<string>NSObject</string>
			</array>
			<key>$classname</key>
			<string>NSMutableDictionary</string>
		</dict>
	</array>
	<key>$top</key>
	<dict>
		<key>root</key>
		<dict>
			<key>CF$UID</key>
			<integer>1</integer>
		</dict>
	</dict>
	<key>$version</key>
	<integer>100000</integer>
</dict>
</plist>

Where is my thinking error? I know there are key value pairs but how can i access them easily?
Thanks to every response.

Benno

I don’t think you’re doing anything wrong — at least, it’s not responding to the obvious things here. That early FSKeyedArchiver makes me wonder if it’s not coded with NSKeyedArchiver — a quick Web search does throw up a third-party FSKeyedArchiver class.

Do you know what the value for FAT_ImportoRitenuta is in this file? There might be an unorthodox approach that works.

Shane i appreciate your response.
Nice to here that i am on the right way.

The Value for the Key “FAT_ImportoRitenuta” is “54.05”. The Line underneath.

“FSKeyedArchiver” is a third-party NSKeyedArchiver class from F-Script. Some information can be found here: https://en.wikipedia.org/wiki/F-Script_(programming_language). In the Documentation in my hand there is written: “F-Script uses NSArchiver to save objects. So, objects to be saved must conform to the standard Cocoa NSCoding protocol. Files generated are standard NSArchiver files; you can use them with other applications to load archived objects using the Cocoa NSUnarchiver API”

Thx B

I suspect that documentation is a bit out of date. If I try this:

current application's NSUnarchiver's alloc()'s initForReadingWithData:theData

I get missing value, whereas this:

set {theUnarchiver, theError} to current application's NSKeyedUnarchiver's alloc()'s initForReadingFromData:theData |error|:(reference)

at least seems to return a valid keyed unarchiver. But I don’t have any luck getting anything out of it.

At a pinch, you could try parsing the XML directly, as discussed here:

So something like this:

set theDoc to current application's NSXMLDocument's alloc()'s initWithXMLString:theString options:0 |error|:(missing value)
set {theNodes, theError} to theDoc's nodesForXPath:"//string['FAT_ImportoRitenuta'=text()]/following-sibling::string[1]" |error|:(reference)
return theNodes's firstObject()'s stringValue() as text

Thanks Shane.
I tried your idea:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

set theXMLData to (choose file)
set theXMLString to read theXMLData

set theString to current application's NSString's stringWithString:theXMLString
set theDoc to current application's NSXMLDocument's alloc()'s initWithXMLString:theString options:(current application's NSXMLDocumentTidyXML) |error|:(missing value)

set theQuery to "//string['FAT_ImportoRitenuta'=text()]/following-sibling::string[1]"

set {theResults, theError} to (theDoc's nodesForXPath:theQuery |error|:(reference)) -- query

and tried with the Code above.
The Result is an empty Array, but convalidating the XPath query with http://www.xpathtester.com/xquery for exemple i get my desired Values.
Am I loading the file wrong?

Thx

Probably – you’re not reading as UTF-8, but rather MacRoman, so content probably got mangled. I don’t know that you need the NSXMLDocumentTidyXML, but it probably won’t hurt.

This is a more direct way to load it from a file (assuming 10.11 or later):

use AppleScript version "2.5" -- 10.11 or later
use framework "Foundation"
use scripting additions

set theFile to (choose file)
set theDoc to current application's NSXMLDocument's alloc()'s initWithContentsOfURL:theFile options:(current application's NSXMLDocumentTidyXML) |error|:(missing value)
set theQuery to "//string['FAT_ImportoRitenuta'=text()]/following-sibling::string[1]"
set {theResults, theError} to (theDoc's nodesForXPath:theQuery |error|:(reference)) -- query
return theResults's firstObject()'s stringValue() as text