スポンサーサイト

Tags :
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

XML等の文字参照を通常の文字列に戻すAppleScript(その2)

■4/7追記 こちらのエントリにもっとシンプルなのがあります。
Webで利用される様々な文字列エンコードを扱うためのAppleScriptいろいろ


ちょっと前に『&』や『〹』といった文字参照を含む文字列を通常の文字列に戻すAppleScriptてのを書きましたが、あまりに処理が遅いので、もうちょっと速くなるよう書き直しました。

前回のはpythonでforループを一行に納める書き方がわからなかったというのもあって、文字コードを一文字ごとにdo shell scriptでpythonに渡してましたが、それだとやたら時間がかかるので、間にASCII文字が入る等して文字参照が途切れない限り出来るだけ一度にpythonの引数として渡すようにしました。

MacOSX10.5のAppleScriptならpythonを使わなくてもUnicode textのidプロパティで変換できるので、一文字ずつ処理するような書き方でもそれ程遅くならないかも知れません。なのでこのスクリプトは主に10.4以前のOSX向けです。

あと、数値文字参照の表記が10進、16進どちらでも変換できるようにしてあります。

■動作確認■
MacOSX 10.4.11
-- my_string -> 変換する文字参照を含んだ文字列
set my_string to "『&amp&#x3b;』等の実体参照や『&#12345&#x3b;』といった数値文字参照を通常の文字に変換します" as Unicode text

display dialog (decodeStringsWithNCRs(my_string))

on decodeStringsWithNCRs(my_string)
    set resultStr to ""
    set ent to "" as Unicode text
    set ent_list to {}
    set flg to false
    repeat with cnt from 1 to (count of my_string)
        set chr to item cnt of my_string
        if chr is "&" and (item (cnt + 1) of my_string is not "&") then
            if flg is false then
                set flg to true
                set ent to chr
            else
                set resultStr to resultStr & ent
                set ent to "&"
            end if
        else if chr is ";" and flg is true then
            if ent starts with "&#" then
                set end of ent_list to ent & ";"
            else
                set resultStr to resultStr & decodeNCRs(ent_list) & decodeEntity(ent & ";")
                set ent_list to {}
            end if
            set flg to false
            set ent to ""
        else if flg is true then
            set ent to ent & chr
        else
            if ent_list is not {} then
                set resultStr to resultStr & decodeNCRs(ent_list) & chr
                set ent_list to {}
            else
                set resultStr to resultStr & chr
            end if
        end if        
    end repeat
    set resultStr to resultStr & decodeNCRs(ent_list)
end decodeStringsWithNCRs


on decodeNCRs(ncr_list)
    set args to "" as Unicode text
    repeat with w in ncr_list
        set w to items 3 thru -2 of w
        if w starts with "x" then set w to "0" & w
        set args to args & " " & w
    end repeat
    try
        set scpt to "python -c 'import sys;[sys.stdout.write(unichr(eval(i)).encode(\"utf-8\")) for i in sys.argv[1:]] ' " & args
        return do shell script scpt
    on error
        return false
    end try
end decodeNCRs


on decodeEntity(str)
    set html_ent to {"&", "<", ">", """, "'"}
    set decoded_ent to {"&", "<", ">", "\"", "'"}
    set cnt to 1
    repeat with he in html_ent
        if str is he as Unicode text then
            return item cnt of decoded_ent
        end if
        set cnt to cnt + 1
    end repeat
    return str
end decodeEntity
関連記事
スポンサーサイト

コメント

非公開コメント

Profile
choco
Author : choco

印刷・製版の現場を経て、広告制作会社でPhotoshopを使ったビジュアル制作を担当。

→現在は車載機器開発ベンダにて、組み込み3Dデータ作成やUIデザインなどを行っています。

Categories
Favorites


Search
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。