AppleScript名:2D ListをCSVに v3(サニタイズ処理つき) |
— Created 2015-10-01 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aNewFile to choose file name set dataList to {{"0010", "ひよこタオルギフト", "200", "手に取ったとき、\"使うとき\"、ちょっと楽しくてかわいいひよこのタオル。", "●サイズ/H200㎜×W200㎜●素材/ひよこ羽毛100%●重量/170g●内容/5枚入り"}, {"0020", "ひよこホイッスル", "250", "今までにないデザインの、ひよこ型のホイッスル。ぴよ〜音を音階で吹き分けます。", "●サイズ/H60㎜×W40㎜×D10㎜●素材/プラスチック ●色/ひよこ色●重量/10g●付属品/首かけロープ付き ●型番/PIYO1"}} saveAsCSV(dataList, aNewFile) of me –2D List to CSV file on saveAsCSV(aList, aPath) –set crlfChar to (ASCII character 13) & (ASCII character 10) set crlfChar to (string id 13) & (string id 10) set LF to (string id 10) set wholeText to "" repeat with i in aList set newLine to {} –Sanitize (Double Quote) repeat with ii in i set jj to ii as text set kk to repChar(jj, string id 34, (string id 34) & (string id 34)) of me –Escape Double Quote set the end of newLine to kk end repeat –Change Delimiter set aLineText to "" set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to "\",\"" set aLineList to newLine as text set AppleScript’s text item delimiters to curDelim set aLineText to repChar(aLineList, return, "") of me –delete return set aLineText to repChar(aLineText, LF, "") of me –delete lf set wholeText to wholeText & "\"" & aLineText & "\"" & crlfChar –line terminator: CR+LF end repeat if (aPath as string) does not end with ".csv" then set bPath to aPath & ".csv" as Unicode text else set bPath to aPath as Unicode text end if write_to_file(wholeText, bPath, false) of me end saveAsCSV on write_to_file(this_data, target_file, append_data) tell current application try set the target_file to the target_file as text set the open_target_file to open for access file target_file with write permission if append_data is false then set eof of the open_target_file to 0 write this_data to the open_target_file starting at eof close access the open_target_file return true on error error_message try close access file target_file end try return error_message end try end tell end write_to_file on repChar(origText as text, targChar as text, repChar as text) set curDelim to AppleScript’s text item delimiters set AppleScript’s text item delimiters to targChar set tmpList to text items of origText set AppleScript’s text item delimiters to repChar set retText to tmpList as string set AppleScript’s text item delimiters to curDelim return retText end repChar |
タグ: 10.11savvy
CSVのParse 5(ASOC)
AppleScript名:CSVのParse 5(ASOC) |
–Created By Shane Stanley 2015/03/12 –Commented & Arranged By Takaaki Naganoya 2015/03/12 use scripting additions use framework "Foundation" set theString to "cust1,\"prod,1\",season 1, cust1,prod1,season2, cust2,prod1,event1,season1 cust2,prod3,event1,season 1" its makeListsFromCSV:theString commaIs:"," –> {{"cust1", "prod,1", "season 1"}, {"cust1", "prod1", "season2"}, {"cust2", "prod1", "event1", "season1"}, {"cust2", "prod3", "event1", "season 1"}} –CSV Parser ASOC ver (Translated from "ASObjCExtras.framework" Objective-C version) on makeListsFromCSV:theString commaIs:theComma set theRows to {} –最終的に出力するデータ(2D Listになる) set newLineCharSet to current application’s NSCharacterSet’s newlineCharacterSet() –改行キャラクタ set importantCharSet to current application’s NSMutableCharacterSet’s characterSetWithCharactersInString:("\"" & theComma) –カンマ importantCharSet’s formUnionWithCharacterSet:newLineCharSet set theNSScanner to current application’s NSScanner’s scannerWithString:theString theNSScanner’s setCharactersToBeSkipped:(missing value) –データ末尾を検出するまでループ repeat while (theNSScanner’s isAtEnd() as integer = 0) set insideQuotes to false set finishedRow to false set theColumns to {} set currentColumn to "" –すべての行を処理終了するまでループ(行内部の処理) repeat while (not finishedRow) set {theResult, tempString} to theNSScanner’s scanUpToCharactersFromSet:importantCharSet intoString:(reference) –log {"theResult", theResult, "tempString", tempString} if theResult as integer = 1 then set currentColumn to currentColumn & (tempString as text) –log {"currentColumn", currentColumn} –データ末尾検出 if theNSScanner’s isAtEnd() as integer = 1 then if currentColumn is not "" then set end of theColumns to currentColumn set finishedRow to true else –データ末尾ではない場合 set {theResult, tempString} to theNSScanner’s scanCharactersFromSet:newLineCharSet intoString:(reference) if theResult as integer = 1 then if insideQuotes then –ダブルクォート文字内の場合 set currentColumn to currentColumn & (tempString as text) else –ダブルクォート内ではない場合 if currentColumn is not "" then set end of theColumns to currentColumn set finishedRow to true end if else –行末文字が見つからない場合 set theResult to theNSScanner’s scanString:"\"" intoString:(missing value) if theResult as integer = 1 then –ダブルクォート文字が見つかった場合 if insideQuotes then –ダブルクォート文字内の場合 set theResult to theNSScanner’s scanString:"\"" intoString:(missing value) if theResult as integer = 1 then set currentColumn to currentColumn & "\"" else set insideQuotes to (not insideQuotes) end if else –ダブルクォート文字内ではない場合 set insideQuotes to (not insideQuotes) end if else –ダブルクォート文字が見つからなかった場合 set theResult to theNSScanner’s scanString:theComma intoString:(missing value) –カンマの検索 if theResult as integer = 1 then if insideQuotes then set currentColumn to currentColumn & theComma else set end of theColumns to currentColumn set currentColumn to "" theNSScanner’s scanCharactersFromSet:(current application’s NSCharacterSet’s whitespaceCharacterSet()) intoString:(missing value) end if end if end if end if end if end repeat if (count of theColumns) > 0 then set end of theRows to theColumns –行データ(1D List)をtheRowsに追加(2D List) end repeat return theRows end makeListsFromCSV:commaIs: |
CSVのParse 4a(ASOC)
AppleScript名:CSVのParse 4a(ASOC) |
— Created 2015-03-11 by Shane Stanley use AppleScript version "2.4" use scripting additions use framework "Foundation" use Bplus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html load framework set someString to read (choose file of type {"public.comma-separated-values-text"}) set theData to current application’s SMSForder’s arrayFromCSV:someString commaIs:"," set theData to (current application’s SMSForder’s subarraysIn:theData paddedWith:"" |error|:(missing value)) as list –> {{"cust1", "prod,1", "season 1", ""}, {"cust1", "prod1", "season 2", ""}, {"cust2", "prod1", "event1", "season 1"}, {"cust2", "prod2", "event1", "season 2"}, {"cust2", "prod3", "event1", "season 1"}} |
RSSをダウンロードしてparseする(XmlToDictKit)
AppleScript名:RSSをダウンロードしてparseする(XmlToDictKit) |
— Created 2016-11-05 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "XmlToDictKit" –https://github.com/nicklockwood/XMLDictionary set aURL to current application’s |NSURL|’s alloc()’s initWithString:"http://piyocast.com/as/feed/" set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) if xmlString = missing value then return false set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) set blogTitle to (xmlDoc’s valueForKeyPath:"channel.title") as string –> "AppleScirpt Hole" –タイトル一覧を取得する set titleList to (xmlDoc’s valueForKeyPath:"channel.item.title") as list –> {"XmlToDictKitでBlogのRSS情報を解析", "listのrecordをplistにserializeして、plistをde-serializeする", "Listのrecordをエンコーディングしてplist文字列にする", "serializeされたlistのrecordからKeynoteで新規ドキュメントを作成してグラフを作成", "system_profilerの結果のstringのplistをdictionaryにのコピー2", "XPathQuery4ObjCのじっけん2", "recordをXMLに v2", "XmlToDictKitでXMLをDictionaryに(remote file)", "XmlToDictKitでXMLをDictionaryに(local file)", "XMLをrecordにv2"} –URL一覧を返す set urlList to (xmlDoc’s valueForKeyPath:"channel.item.link") as list –> {"http://piyocast.com/as/archives/814", "http://piyocast.com/as/archives/812", "http://piyocast.com/as/archives/810", "http://piyocast.com/as/archives/805", "http://piyocast.com/as/archives/803", "http://piyocast.com/as/archives/799", "http://piyocast.com/as/archives/797", "http://piyocast.com/as/archives/792", "http://piyocast.com/as/archives/790", "http://piyocast.com/as/archives/788"} –本文のプレビュー一覧 set descList to (xmlDoc’s valueForKeyPath:"channel.item.description") as list (* {"AppleScript名:XmlToDictKitでBlogのRSS情報を解析 — Created 2016-11-05 by Takaaki Naganoya— 2016 Piyomaru S … <a href=\"http://piyocast.com/as/archives/814\" class=\"more-link\"><span class=\"screen-reader-text\">\"XmlToDictKitでBlogのRSS情報を解析\"の</span>続きを読む</a>", …. *) –更新日時の一覧 set descList to (xmlDoc’s valueForKeyPath:"channel.item.pubDate") as list –> {"Wed, 07 Feb 2018 08:00:53 +0000", "Wed, 07 Feb 2018 07:58:06 +0000", "Wed, 07 Feb 2018 07:55:12 +0000", "Wed, 07 Feb 2018 07:50:07 +0000", "Wed, 07 Feb 2018 07:28:10 +0000", "Wed, 07 Feb 2018 07:23:45 +0000", "Wed, 07 Feb 2018 07:23:04 +0000", "Wed, 07 Feb 2018 07:20:21 +0000", "Wed, 07 Feb 2018 07:20:13 +0000", "Wed, 07 Feb 2018 07:11:33 +0000"} |
XmlToDictKitでBlogのRSS情報を解析
AppleScript名:XmlToDictKitでBlogのRSS情報を解析 |
— Created 2016-11-05 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "XmlToDictKit" –https://github.com/nicklockwood/XMLDictionary set aURL to "http://piyocast.com/as/feed/" set xRes to getLatestBlogInfo(aURL) of me on getLatestBlogInfo(aURLstring) set aURL to current application’s |NSURL|’s alloc()’s initWithString:aURLstring set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) if xmlString = missing value then return false set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) set blogTitle to (xmlDoc’s valueForKeyPath:"channel.title") as string –> "AS Hole(AppleScriptの穴) By Piyomaru Software" set titleList to (xmlDoc’s valueForKeyPath:"channel.item.title") as list –タイトル一覧 set urlList to (xmlDoc’s valueForKeyPath:"channel.item.link") as list –URL一覧 set descList to (xmlDoc’s valueForKeyPath:"channel.item.description") as list –本文のプレビュー一覧 set updateList to (xmlDoc’s valueForKeyPath:"channel.item.pubDate") as list –更新日時の一覧 return {first item of titleList, first item of urlList, first item of descList} end getLatestBlogInfo |
listのrecordをplistにserializeして、plistをde-serializeする
AppleScript名:listのrecordをplistにserializeして、plistをde-serializeする |
— Created 2016-10-30 by Takaaki Naganoya — Modified 2016-10-31 by Shane Stanley — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aList to {{theName:"サウンドトラック", numberOfTimes:1721}, {theName:"ロック", numberOfTimes:942}, {theName:"クラシック", numberOfTimes:539}, {theName:"ポップ", numberOfTimes:492}, {theName:"J-Pop", numberOfTimes:352}, {theName:"アニメ", numberOfTimes:330}, {theName:"Pop", numberOfTimes:279}, {theName:"World", numberOfTimes:218}, {theName:"Soundtrack", numberOfTimes:188}, {theName:"ジャズ", numberOfTimes:187}, {theName:"エレクトロニック", numberOfTimes:166}, {theName:"Classical", numberOfTimes:165}, {theName:"Rock", numberOfTimes:148}, {theName:"R&B", numberOfTimes:125}, {theName:"ニューエイジ", numberOfTimes:104}, {theName:"Unclassifiable", numberOfTimes:81}, {theName:"Children’s", numberOfTimes:57}, {theName:"歌謡曲", numberOfTimes:47}, {theName:"Holiday", numberOfTimes:38}, {theName:"オルタナティブ", numberOfTimes:34}, {theName:"Data", numberOfTimes:32}, {theName:"イージーリスニング", numberOfTimes:31}, {theName:"ヴォーカル", numberOfTimes:28}, {theName:"ワールド", numberOfTimes:28}, {theName:"soundtrack", numberOfTimes:19}, {theName:"ディズニー", numberOfTimes:15}, {theName:"シンガーソングライター", numberOfTimes:15}, {theName:"ブルース", numberOfTimes:15}, {theName:"Easy Listening", numberOfTimes:14}, {theName:"ラテン", numberOfTimes:14}, {theName:"Electronica/Dance", numberOfTimes:14}, {theName:"Anime", numberOfTimes:13}, {theName:"フォーク", numberOfTimes:10}, {theName:"J-POP", numberOfTimes:9}, {theName:"New Age", numberOfTimes:9}, {theName:"ダンス", numberOfTimes:5}, {theName:"ホリデー", numberOfTimes:5}, {theName:"カントリー", numberOfTimes:4}, {theName:"演歌", numberOfTimes:4}, {theName:"Latin", numberOfTimes:3}, {theName:"ヒップホップ/ラップ", numberOfTimes:3}, {theName:"Vocal", numberOfTimes:2}, {theName:"R&B/ソウル", numberOfTimes:2}, {theName:"R&B/ソウル", numberOfTimes:2}, {theName:"#NIPPONSEI @ IRC.MIRCX.COM", numberOfTimes:2}, {theName:"148", numberOfTimes:1}, {theName:"Electronic", numberOfTimes:1}, {theName:"Folk", numberOfTimes:1}, {theName:"NHK FM(東京)", numberOfTimes:1}, {theName:"その他", numberOfTimes:1}, {theName:"チルドレン・ミュージック", numberOfTimes:1}, {theName:"Seattle Pacific University – Latin", numberOfTimes:1}, {theName:"Kayokyoku", numberOfTimes:1}, {theName:"ヒップホップ/ ラップ", numberOfTimes:1}, {theName:"Dance", numberOfTimes:1}, {theName:"インストゥルメンタル", numberOfTimes:1}, {theName:"146", numberOfTimes:1}} set aRes to serializeToPlistString(aList) of me –>"<?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\"><array><dict><key>numberOfTimes</key><integer>1721</integer><key>theName</key><string>サウンドトラック</string></dict>…. set bRes to (deserializeToPlistString(aRes) of me) as list –> {{numberOfTimes:1721, theName:"Sound Track"}, {numberOfTimes:942, theName:"Rock"}} –list or record –> XML-format plist string on serializeToPlistString(aList as {list, record}) set pListData to current application’s NSPropertyListSerialization’s dataWithPropertyList:aList |format|:(current application’s NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value) set bStr to (current application’s NSString’s alloc()’s initWithData:pListData encoding:(current application’s NSUTF8StringEncoding)) as string return bStr end serializeToPlistString –XML-format plist string–> list or record on deserializeToPlistString(aStr as string) set deStr to current application’s NSString’s stringWithString:aStr set theData to deStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aList to current application’s NSPropertyListSerialization’s propertyListWithData:theData options:(current application’s NSPropertyListMutableContainersAndLeaves) |format|:(missing value) |error|:(missing value) return aList end deserializeToPlistString |
Listのrecordをエンコーディングしてplist文字列にする
AppleScript名:Listのrecordをエンコーディングしてplist文字列にする |
— Created 2016-10-30 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" –http://piyocast.com/as/archives/4295 set aList to {{theName:"サウンドトラック", numberOfTimes:1721}, {theName:"ロック", numberOfTimes:942}} –2D Arrayをplistの文字列にエンコードする set anArray to current application’s NSArray’s arrayWithObject:aList set pListData to current application’s NSPropertyListSerialization’s dataFromPropertyList:anArray |format|:(current application’s NSPropertyListXMLFormat_v1_0) errorDescription:(missing value) set bStr to (current application’s NSString’s alloc()’s initWithData:pListData encoding:(current application’s NSUTF8StringEncoding)) as string (* –> "<?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\"> <array> <array> <dict> <key>numberOfTimes</key> <integer>1721</integer> <key>theName</key> <string>サウンドトラック</string> </dict> <dict> <key>numberOfTimes</key> <integer>942</integer> <key>theName</key> <string>ロック</string> </dict> </array> </array> </plist> " *) |
serializeされたlistのrecordからKeynoteで新規ドキュメントを作成してグラフを作成
AppleScript名:serializeされたlistのrecordからKeynoteで新規ドキュメントを作成してグラフを作成 |
— Created 2016-10-31 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set selData to retSerializedData() of me set aList to (deserializeToPlistString(selData) of me) as list set aLen to length of aList if aLen > 10 then set bList to items 1 thru 10 of aList else copy aList to bList end if makeKeynoteGraph(bList, "自分のiTunesライブラリ中のジャンル内訳") of me on makeKeynoteGraph(bList, aTitle) set labelList to {} set dataList to {} repeat with i from 1 to (length of bList) set the end of labelList to contents of theName of (item i of bList) set the end of dataList to contents of numberOfTimes of (item i of bList) end repeat set targWidth to 500 set targHeight to 500 tell application "Keynote" activate set thisDocument to make new document with properties {height:764, width:1024, document theme:theme "ホワイト"} tell thisDocument set aHeight to height set aWidth to width tell slide 1 set base slide to master slide "タイトル(上)" of thisDocument set object text of default title item to aTitle tell default title item set height to 80 end tell (add chart row names {"ROW A"} column names labelList data {dataList} type pie_2d group by chart column) tell chart 1 set width to targWidth set height to targHeight set position to {(aWidth / 2) – (targWidth / 2), (aHeight / 2) – (targHeight / 2) + 20} end tell end tell end tell end tell end makeKeynoteGraph on retSerializedData() return "<?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\"> <array> <dict> <key>numberOfTimes</key> <integer>1721</integer> <key>theName</key> <string>サウンドトラック</string> </dict> <dict> <key>numberOfTimes</key> <integer>942</integer> <key>theName</key> <string>ロック</string> </dict> <dict> <key>numberOfTimes</key> <integer>539</integer> <key>theName</key> <string>クラシック</string> </dict> <dict> <key>numberOfTimes</key> <integer>492</integer> <key>theName</key> <string>ポップ</string> </dict> <dict> <key>numberOfTimes</key> <integer>352</integer> <key>theName</key> <string>J-Pop</string> </dict> <dict> <key>numberOfTimes</key> <integer>330</integer> <key>theName</key> <string>アニメ</string> </dict> <dict> <key>numberOfTimes</key> <integer>279</integer> <key>theName</key> <string>Pop</string> </dict> <dict> <key>numberOfTimes</key> <integer>218</integer> <key>theName</key> <string>World</string> </dict> <dict> <key>numberOfTimes</key> <integer>188</integer> <key>theName</key> <string>Soundtrack</string> </dict> <dict> <key>numberOfTimes</key> <integer>187</integer> <key>theName</key> <string>ジャズ</string> </dict> <dict> <key>numberOfTimes</key> <integer>166</integer> <key>theName</key> <string>エレクトロニック</string> </dict> <dict> <key>numberOfTimes</key> <integer>165</integer> <key>theName</key> <string>Classical</string> </dict> <dict> <key>numberOfTimes</key> <integer>148</integer> <key>theName</key> <string>Rock</string> </dict> <dict> <key>numberOfTimes</key> <integer>125</integer> <key>theName</key> <string>R&B</string> </dict> <dict> <key>numberOfTimes</key> <integer>104</integer> <key>theName</key> <string>ニューエイジ</string> </dict> <dict> <key>numberOfTimes</key> <integer>81</integer> <key>theName</key> <string>Unclassifiable</string> </dict> <dict> <key>numberOfTimes</key> <integer>57</integer> <key>theName</key> <string>Children’s</string> </dict> <dict> <key>numberOfTimes</key> <integer>47</integer> <key>theName</key> <string>歌謡曲</string> </dict> <dict> <key>numberOfTimes</key> <integer>38</integer> <key>theName</key> <string>Holiday</string> </dict> <dict> <key>numberOfTimes</key> <integer>34</integer> <key>theName</key> <string>オルタナティブ</string> </dict> <dict> <key>numberOfTimes</key> <integer>32</integer> <key>theName</key> <string>Data</string> </dict> <dict> <key>numberOfTimes</key> <integer>31</integer> <key>theName</key> <string>イージーリスニング</string> </dict> <dict> <key>numberOfTimes</key> <integer>28</integer> <key>theName</key> <string>ヴォーカル</string> </dict> <dict> <key>numberOfTimes</key> <integer>28</integer> <key>theName</key> <string>ワールド</string> </dict> <dict> <key>numberOfTimes</key> <integer>19</integer> <key>theName</key> <string>soundtrack</string> </dict> <dict> <key>numberOfTimes</key> <integer>15</integer> <key>theName</key> <string>ディズニー</string> </dict> <dict> <key>numberOfTimes</key> <integer>15</integer> <key>theName</key> <string>シンガーソングライター</string> </dict> <dict> <key>numberOfTimes</key> <integer>15</integer> <key>theName</key> <string>ブルース</string> </dict> <dict> <key>numberOfTimes</key> <integer>14</integer> <key>theName</key> <string>Easy Listening</string> </dict> <dict> <key>numberOfTimes</key> <integer>14</integer> <key>theName</key> <string>ラテン</string> </dict> <dict> <key>numberOfTimes</key> <integer>14</integer> <key>theName</key> <string>Electronica/Dance</string> </dict> <dict> <key>numberOfTimes</key> <integer>13</integer> <key>theName</key> <string>Anime</string> </dict> <dict> <key>numberOfTimes</key> <integer>10</integer> <key>theName</key> <string>フォーク</string> </dict> <dict> <key>numberOfTimes</key> <integer>9</integer> <key>theName</key> <string>J-POP</string> </dict> <dict> <key>numberOfTimes</key> <integer>9</integer> <key>theName</key> <string>New Age</string> </dict> <dict> <key>numberOfTimes</key> <integer>5</integer> <key>theName</key> <string>ダンス</string> </dict> <dict> <key>numberOfTimes</key> <integer>5</integer> <key>theName</key> <string>ホリデー</string> </dict> <dict> <key>numberOfTimes</key> <integer>4</integer> <key>theName</key> <string>カントリー</string> </dict> <dict> <key>numberOfTimes</key> <integer>4</integer> <key>theName</key> <string>演歌</string> </dict> <dict> <key>numberOfTimes</key> <integer>3</integer> <key>theName</key> <string>Latin</string> </dict> <dict> <key>numberOfTimes</key> <integer>3</integer> <key>theName</key> <string>ヒップホップ/ラップ</string> </dict> <dict> <key>numberOfTimes</key> <integer>2</integer> <key>theName</key> <string>Vocal</string> </dict> <dict> <key>numberOfTimes</key> <integer>2</integer> <key>theName</key> <string>R&B/ソウル</string> </dict> <dict> <key>numberOfTimes</key> <integer>2</integer> <key>theName</key> <string>R&B/ソウル</string> </dict> <dict> <key>numberOfTimes</key> <integer>2</integer> <key>theName</key> <string>#NIPPONSEI @ IRC.MIRCX.COM</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>148</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>Electronic</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>Folk</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>NHK FM(東京)</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>その他</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>チルドレン・ミュージック</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>Seattle Pacific University – Latin</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>Kayokyoku</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>ヒップホップ/ ラップ</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>Dance</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>インストゥルメンタル</string> </dict> <dict> <key>numberOfTimes</key> <integer>1</integer> <key>theName</key> <string>146</string> </dict> </array> </plist> " end retSerializedData –list or record –> XML-format plist string on serializeToPlistString(aList as {list, record}) set pListData to current application’s NSPropertyListSerialization’s dataWithPropertyList:aList |format|:(current application’s NSPropertyListXMLFormat_v1_0) options:0 |error|:(missing value) set bStr to (current application’s NSString’s alloc()’s initWithData:pListData encoding:(current application’s NSUTF8StringEncoding)) as string return bStr end serializeToPlistString –XML-format plist string–> list or record on deserializeToPlistString(aStr as string) set deStr to current application’s NSString’s stringWithString:aStr set theData to deStr’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aList to current application’s NSPropertyListSerialization’s propertyListWithData:theData options:(current application’s NSPropertyListMutableContainersAndLeaves) |format|:(missing value) |error|:(missing value) return aList end deserializeToPlistString |
system_profilerの結果のstringのplistをdictionaryにのコピー2
AppleScript名:system_profilerの結果のstringのplistをdictionaryにのコピー2 |
— Created 2015-11-01 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aTargKey to "machine_name" set aTargGenre to "SPHardwareDataType" set macRes to getSystemProfileInAGenre(aTargGenre, aTargKey) of me –> "MacBook Pro" on getSystemProfileInAGenre(aTargGenre, aTargKey) set sRes to do shell script ("/usr/sbin/system_profiler -xml " & aTargGenre) set aSource to (my readPlistFromStr:sRes) as list set aaList to contents of first item of aSource set aList to _items of aaList repeat with i in aList set aDict to (current application’s NSMutableDictionary’s dictionaryWithDictionary:(contents of i)) set aKeyList to (aDict’s allKeys()) as list if aTargKey is in aKeyList then set aRes to (aDict’s valueForKeyPath:aTargKey) if aRes is not equal to missing value then return aRes as string end if end if end repeat return false end getSystemProfileInAGenre –stringのplistを読み込んでRecordに on readPlistFromStr:theString set aSource to current application’s NSString’s stringWithString:theString set pListData to aSource’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) set aPlist to current application’s NSPropertyListSerialization’s propertyListFromData:pListData mutabilityOption:(current application’s NSPropertyListImmutable) |format|:(current application’s NSPropertyListFormat) errorDescription:(missing value) return aPlist end readPlistFromStr: |
XPathQuery4ObjCのじっけん2
XMLに対して、オープンソースの「XPathQuery4ObjC」を用いてXPathを指定してXML内の要素にアクセスするAppleScriptです。
XMLに対してXpathを指定してアクセスする道具はいろいろあります。
Syetem Eventsを使ってXMLにアクセスする方法、XMLLib OSAX、オープンソースのObjective-CのプログラムをCocoa Framework化したもの、etc。
ただ、macOS 10.14でOSAXが事実上使えなくなったことを考えると、OSAXによるAppleScriptの予約語拡張は得策ではありません。System Eventsも1つの解決策ではありますが、XPathが使えないのでほとんど使いません。
こうしたObjective-Cで記述されたプログラムをAppleScriptから呼び出すのが、現状でもっとも効率のよい解決策です。各プログラムはだいたいにおいて挙動が異なり、XMLの構造も一様ではありません。複数のプログラムをためして、対象のXMLを思い通りに処理できるか、総当たりで確認しています。
AppleScript名:XPathQuery4ObjCのじっけん2 |
— Created 2017-01-05 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "XPathQueryKit" –https://github.com/cybergarage/XPathQuery4ObjC –http://piyocast.com/as/archives/4376 set rssURL to current application’s |NSURL|’s URLWithString:"http://piyocast.com/as/feed" set xpathQuery to current application’s CGXPathQuery’s alloc()’s initWithContentsOfURL:rssURL if ((xpathQuery’s parse()) as boolean) = true then set entriesList to xpathQuery’s objectsForXPath:"/rss/channel/item" repeat with itemObject in entriesList set aChild to itemObject’s children() log aChild set aTitle to (itemObject’s valueForXPath:"title") log aTitle as string set aLink to (itemObject’s valueForXPath:"link") log aLink as string set aComments to (itemObject’s valueForXPath:"comments") log aComments as string set aPubdate to (itemObject’s valueForXPath:"pubDate") log aPubdate as string set aCreator to (itemObject’s valueForXPath:"dc:creator") log aCreator as string set aCategory to (itemObject’s valuesForXPath:"category") log aCategory as list set aGUID to (itemObject’s valuesForXPath:"guid") log aGUID as string set aDesc to (itemObject’s valueForXPath:"description") log aDesc as string set aCommentURL to (itemObject’s valueForXPath:"wfw:commentRss") log aCommentURL as string end repeat end if |
recordをXMLに v2
AppleScript名:recordをXMLに v2 |
use AppleScript version "2.4" use scripting additions use framework "Foundation" set theRecord to {firstName:"Saga", lastName:"Norén", city:"Malmö"} makeXMLDocWithRecord(theRecord) –> (* "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<character>\n <firstName>Saga</firstName>\n <city>Malmö</city>\n <lastName>Norén</lastName>\n</character>" *) set theRecord to {firstName:"Saga", lastName:"Norén", city:"Malmö", partner:{firstName:"Martin", lastName:"Rohde", city:"København"}} makeXMLDocWithRecord(theRecord) –> (* "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<character>\n <firstName>Saga</firstName>\n <lastName>Norén</lastName>\n <city>Malmö</city>\n <partner>\n <firstName>Martin</firstName>\n <city>København</city>\n <lastName>Rohde</lastName>\n </partner>\n</character>" *) –Record –> XML (text) on makeXMLDocWithRecord(theRecord) — make root element set rootElement to current application’s NSXMLNode’s elementWithName:"character" — make XML document set theXMLDocument to current application’s NSXMLDocument’s alloc()’s initWithRootElement:rootElement theXMLDocument’s setDocumentContentKind:(current application’s NSXMLDocumentXMLKind) theXMLDocument’s setStandalone:true theXMLDocument’s setCharacterEncoding:"UTF-8" — make dictionary from record set anNSDictionary to current application’s NSDictionary’s dictionaryWithDictionary:theRecord — add children to root element its addChildTo:rootElement withDictionary:anNSDictionary — return as string with whatever formatting options you want return (theXMLDocument’s XMLStringWithOptions:(current application’s NSXMLNodePrettyPrint)) as text end makeXMLDocWithRecord on addChildTo:parentElement withDictionary:theDict set theKeys to theDict’s allKeys() as list repeat with i from 1 to count of theKeys set theKey to item i of theKeys set theValue to (theDict’s objectForKey:theKey) set newElement to (current application’s NSXMLNode’s elementWithName:theKey) (parentElement’s addChild:newElement) if (theValue’s isKindOfClass:(current application’s NSDictionary)) as boolean then (its addChildTo:newElement withDictionary:theValue) else (newElement’s setObjectValue:theValue) end if end repeat end addChildTo:withDictionary: |
XmlToDictKitでXMLをDictionaryに(remote file)
AppleScript名:XmlToDictKitでXMLをDictionaryに(remote file) |
— Created 2016-11-05 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "XmlToDictKit" –https://github.com/nicklockwood/XMLDictionary set aURL to current application’s |NSURL|’s alloc()’s initWithString:"http://www.ibiblio.org/xml/examples/shakespeare/all_well.xml" set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) if xmlString = missing value then return false set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) as record |
XmlToDictKitでXMLをDictionaryに(local file)
AppleScript名:XmlToDictKitでXMLをDictionaryに(local file) |
— Created 2016-11-05 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "XmlToDictKit" –https://github.com/nicklockwood/XMLDictionary set aFile to POSIX path of (choose file) set aURL to current application’s |NSURL|’s fileURLWithPath:aFile set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) if xmlString = missing value then return false set xmlDoc to (current application’s NSDictionary’s dictionaryWithXMLString:xmlString) as record |
XMLをrecordにv2
XMLを解釈してAppleScriptのレコード型のデータに変換するAppleScriptです。
ひとことにXMLといっても、割と書き方にばらつきがあり、1つのルーチンやライブラリで解決できるというものでもない、ということを日々痛感しています。
さまざまな処理方法をおこなうXML解釈プログラムを用意しておいて、かたっぱしから試して適合するものを使っているというところです。本ルーチンで処理できる(解釈しやすい結果を出せる)XMLもあれば、そうでないものもあることでしょう。
また、解釈したXMLのタグについてもそのままではAppleScriptで取り扱えない(スペースを含むとか、特殊文字を含むとか)ものもあり、
XML → NSDictionary → Record
と、AppleScriptのRecordまで変換してしまうと逆に取り扱いにくい場合もあるため、
XML → NSDictionary
と、とどめておいて適宜NSDictionaryからデータを取り出すような処理を行うこともあります。
AppleScript名:XMLをrecordにv2 |
–2015 Shane Stanley & Alex Zavatone — Modified 2016-11-06 by Takaaki Naganoya use AppleScript version "2.4" use scripting additions use framework "Foundation" property dictStack : missing value — stack to hold array of dictionaries property textInProgress : "" — string to collect text as it is found property anError : missing value — if we get an error, store it here set xmlRes to my makeRecordWithXML:(returnData() of me) –> {|character|:{firstName:{|contents|:"Saga"}, lastName:{|contents|:"Norén"}, city:{|contents|:"Malmö"}, partner:{firstName:{|contents|:"Martin"}, lastName:{|contents|:"Rohde"}, city:{|contents|:"København"}, attributes:{approach:"dogged"}}}} on makeRecordWithXML:xmlString — set up properties set my dictStack to current application’s NSMutableArray’s array() — empty mutable array set anEmpty to current application’s NSMutableDictionary’s |dictionary|() (my dictStack)’s addObject:anEmpty — add empty mutable dictionary set my textInProgress to current application’s NSMutableString’s |string|() — empty mutable string — convert XML from string to data set anNSString to current application’s NSString’s stringWithString:xmlString set theData to anNSString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) — initialize an XML parser with the data set theNSXMLParser to current application’s NSXMLParser’s alloc()’s initWithData:theData — set this script to be the parser’s delegate theNSXMLParser’s setDelegate:me — tell it to parse the XML set theResult to theNSXMLParser’s parse() if theResult then — went OK, get first item on stack return ((my dictStack)’s firstObject()) –as record else — error, so return error error (my anError’s localizedDescription() as text) end if end makeRecordWithXML: — this is an XML parser delegate method. Called when new element found on parser:anNSXMLParser didStartElement:elementName namespaceURI:aString qualifiedName:qName attributes:aRecord — store reference to last item on the stack set parentDict to my dictStack’s lastObject() — make new child set childDict to current application’s NSMutableDictionary’s |dictionary|() — if there are attributes, add them as a record with key "attributes" if aRecord’s |count|() > 0 then childDict’s setValue:aRecord forKey:"attributes" end if — see if there’s already an item for this key set existingValue to parentDict’s objectForKey:elementName if existingValue is not missing value then — there is, so if it’s an array, store it… if (existingValue’s isKindOfClass:(current application’s NSMutableArray)) as boolean then set theArray to existingValue else — otherwise create an array and add it set theArray to current application’s NSMutableArray’s arrayWithObject:existingValue parentDict’s setObject:theArray forKey:elementName end if — then add the new dictionary to the array theArray’s addObject:childDict else — add new dictionary directly to the parent parentDict’s setObject:childDict forKey:elementName end if — also add the new dictionary to the end of the stack (my dictStack)’s addObject:childDict end parser:didStartElement:namespaceURI:qualifiedName:attributes: — this is an XML parser delegate method. Called at the end of an element on parser:anNSXMLParser didEndElement:elementName namespaceURI:aString qualifiedName:qName — if any text has been stored, add it as a record with key "contents" if my textInProgress’s |length|() > 0 then set dictInProgress to my dictStack’s lastObject() dictInProgress’s setObject:textInProgress forKey:"contents" — reset textInProgress property for next element set my textInProgress to current application’s NSMutableString’s |string|() end if — remove last item from the stack my dictStack’s removeLastObject() end parser:didEndElement:namespaceURI:qualifiedName: — this is an XML parser delegate method. Called when string is found. May be called repeatedly on parser:anNSXMLParser foundCharacters:aString — only append string if it’s not solely made of space characters (which should be, but aren’t, caught by another delegate method) if (aString’s stringByTrimmingCharactersInSet:(current application’s NSCharacterSet’s whitespaceAndNewlineCharacterSet()))’s |length|() > 0 then (my textInProgress)’s appendString:aString end if end parser:foundCharacters: — this is an XML parser delegate method. Called when there’s an error on parser:anNSXMLParser parseErrorOccurred:anNSError set my anError to anNSError end parser:parseErrorOccurred: on returnData() return "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <rss version=\"2.0\" xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:dcndl=\"http://ndl.go.jp/dcndl/terms/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:dcmitype=\"http://purl.org/dc/dcmitype/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:openSearch=\"http://a9.com/-/spec/opensearchrss/1.0/\" xmlns:rdfs=\"http://www.w3.org/2000/01/rdf-schema#\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"> <channel> <title>Mac使いへの道 – 国立国会図書館サーチ OpenSearch</title> <link>http://iss.ndl.go.jp/api/opensearch?title=Mac%E4%BD%BF%E3%81%84%E3%81%B8%E3%81%AE%E9%81%93</link> <description>Search results for title=Mac使いへの道 </description> <language>ja</language> <openSearch:totalResults>1</openSearch:totalResults> <openSearch:startIndex>1</openSearch:startIndex> <openSearch:itemsPerPage></openSearch:itemsPerPage> <item> <title>Mac使いへの道</title> <link>http://iss.ndl.go.jp/books/R100000002-I000003026578-00</link> <description> <![CDATA[<p>ソフトバンクパブリッシング,4797316489</p> <ul><li>タイトル: Mac使いへの道</li> <li>タイトル(読み): Macツカイ エノ ミチ</li> <li>責任表示: 長野谷隆昌 著,</li> <li>NDC(9): 548.29</li> </ul>]]> </description> <author>長野谷隆昌 著,</author> <category>本</category> <guid isPermaLink=\"true\">http://iss.ndl.go.jp/books/R100000002-I000003026578-00</guid> <pubDate>Thu, 08 May 2003 09:00:00 +0900</pubDate> <dc:title>Mac使いへの道</dc:title> <dcndl:titleTranscription>Macツカイ エノ ミチ</dcndl:titleTranscription> <dc:creator>長野谷隆昌 著</dc:creator> <dc:publisher>ソフトバンクパブリッシング</dc:publisher> <dcterms:issued xsi:type=\"dcterms:W3CDTF\">2001</dcterms:issued> <dc:identifier xsi:type=\"dcndl:ISBN\">4797316489</dc:identifier> <dc:identifier xsi:type=\"dcndl:JPNO\">20206272</dc:identifier> <dc:subject>コンピュータ</dc:subject> <dc:subject xsi:type=\"dcndl:NDLC\">M154</dc:subject> <dc:subject xsi:type=\"dcndl:NDC9\">548.29</dc:subject> <dcterms:description>文献あり</dcterms:description> <rdfs:seeAlso rdf:resource=\"http://id.ndl.go.jp/bib/000003026578\"/> </item> </channel> </rss>" end returnData |
PKXMLKitでRSSをrecordに
AppleScript名:PKXMLKitでRSSをrecordに |
— Created 2017-12-18 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "PKXMLKit" –https://github.com/pawankv89/PKXMLParser set aURL to "http://piyocast.com/as/feed/" set aXMLURL to current application’s |NSURL|’s URLWithString:aURL set xmlString to current application’s NSString’s alloc()’s initWithContentsOfURL:aXMLURL encoding:(current application’s NSUTF8StringEncoding) |error|:(missing value) set xmlDoc to current application’s NSDictionary’s dictionaryWithXMLString:xmlString set titleList to (xmlDoc’s valueForKeyPath:"channel.item.title") as list –> {"アドウェア「OSX.Pirrit」のAppleScriptコードを読んでみた", "表示中のCotEditor書類の「次」のファイルを縦書きでオープン", "ハンドラ間接呼び出し", …} |
recordをJSON文字列に
recordをJSON文字列に変換するAppleScriptです。
AppleScript名:recordをJSON文字列に.scpt |
— Created 2015-07-20 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set aRec to {abc:"test", bcd:"test2", cde:"test3"} set aJson to convRecToJson(aRec) of me as string –> "{"abc":"test","bcd":"test2","cde":"test3"}" on convRecToJson(aRec) set aDict to current application’s NSDictionary’s dictionaryWithDictionary:aRec set jsonData to current application’s NSJSONSerialization’s dataWithJSONObject:aDict options:(0 as integer) |error|:(missing value) –0 is NSJSONWritingPrettyPrinted set resString to current application’s NSString’s alloc()’s initWithData:jsonData encoding:(current application’s NSUTF8StringEncoding) return resString end convRecToJson |
ASOCでjson文字列をrecordに
AppleScript名:ASOCでjson文字列をrecordに |
— Created 2015-07-20 by Takaaki Naganoya — 2015 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set jsonText to "{\"abc\":\"test\",\"bcd\":\"test2\",\"cde\":\"test3\"}" set jsonString to current application’s NSString’s stringWithString:jsonText –> (NSString) "{"abc":"test","bcd":"test2","cde":"test3"}" set jsonData to jsonString’s dataUsingEncoding:(current application’s NSUTF8StringEncoding) –> (NSData) <7b226162 63223a22 74657374 222c2262 6364223a 22746573 7432222c 22636465 223a2274 65737433 227d> set aJsonDict to current application’s NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value) –> (NSDictionary) {abc:"test", bcd:"test2", cde:"test3"} set aRec to aJsonDict as record –> {abc:"test", bcd:"test2", cde:"test3"} |
NSDictionaryを値とキーの列挙で作成する 2
AppleScript名:NSDictionaryを値とキーの列挙で作成する 2 |
— Created 2017-03-03 01:16:41 +0900 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set bundleList to {"com.apple.filemerge", "com.barebones.bbedit", "com.barebones.textwrangler"} set dummyList to {"fdummy", "bbedummy", "twdummy"} set aDict to current application’s NSMutableDictionary’s dictionaryWithObjects:dummyList forKeys:bundleList –> (NSDictionary) {com.apple.filemerge:"fdummy", com.barebones.textwrangler:"twdummy", com.barebones.bbedit:"bbedummy"} set aRes to aDict’s valueForKey:"com.barebones.bbedit" –> (NSString) "bbedummy" |
NSDictionaryを値とキーの列挙で作成する
AppleScript名:NSDictionaryを値とキーの列挙で作成する |
— Created 2016-03-02 23:34:42 +0900 by Takaaki Naganoya — 2016 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" set eDic1 to current application’s NSDictionary’s dictionaryWithObjectsAndKeys_(42, "number", "Hello World", "string", missing value) –> (NSDictionary) {number:42, string:"Hello World"} |
asoc_レコードをリストから生成
AppleScript名:asoc_レコードをリストから生成 |
use AppleScript version "2.4" use scripting additions use framework "Foundation" set labelList to {"Address", "Names"} set valueList to {"ここらへん", "ぴよまるさん"} set theResult to current application’s NSDictionary’s dictionaryWithObjects:(valueList) forKeys:(labelList) set aRec to theResult as record –> {Address:"ここらへん", Names:"ぴよまるさん"} |