Lua解析plist成Lua tabel

local plistParser = {}


function plistParser.nextTag(s, i)
    return string.find(s, "<(%/?)([%w:]+)(%/?)>", i)
end


function plistParser.array(s, i)
    local arr, nextTag, array, dictionary = {}, plistParser.nextTag, plistParser.array, plistParser.dictionary
    local ni, j, c, label, empty


    while true do
        ni, j, c, label, empty = nextTag(s, i)
        assert(ni)


        if c == "" then
            if empty == "/" then
                if label == "dict" or label == "array" then
                    arr[#arr+1] = {}
                else
                    arr[#arr+1] = (label == "true") and true or false
                end
            elseif label == "array" then
                arr[#arr+1], i, j = array(s, j+1)
            elseif label == "dict" then
                arr[#arr+1], i, j = dictionary(s, j+1)
            else
                i = j + 1
                ni, j, c, label, empty = nextTag(s, i)


                local val = string.sub(s, i, ni-1)
                if label == "integer" or label == "real" then
                    arr[#arr+1] = tonumber(val)
                else
                    arr[#arr+1] = val
                end
            end
        elseif c == "/" then
            assert(label == "array")
            return arr, j+1, j
        end


        i = j + 1
    end
end


function plistParser.dictionary(s, i)
    local dict, nextTag, array, dictionary = {}, plistParser.nextTag, plistParser.array, plistParser.dictionary
    local ni, j, c, label, empty


    while true do
        ni, j, c, label, empty = nextTag(s, i)
        assert(ni)


        if c == "" then
            if label == "key" then
                i = j + 1
                ni, j, c, label, empty = nextTag(s, i)
                assert(c == "/" and label == "key")


                local key = string.sub(s, i, ni-1)


                i = j + 1
                ni, j, c, label, empty = nextTag(s, i)


                if empty == "/" then
                    if label == "dict" or label == "array" then
                        dict[key] = {}
                    else
                        dict[key] = (label == "true") and true or false
                    end
                else
                    if label == "dict" then
                        local dictData = nil;
                        dictData, i, j = dictionary(s, j+1)
                        local position = string.find(key,"New item");
                        if position then
                            table.insert(dict,dictData);
                            dump(dictData);
                        else
                            dict[key] = dictData;
                        end
                    elseif label == "array" then
                        dict[key], i, j = array(s, j+1)
                    else
                        i = j + 1
                        ni, j, c, label, empty = nextTag(s, i)


                        local val = string.sub(s, i, ni-1)
                        if label == "integer" or label == "real" then
                            dict[key] = tonumber(val)
                        else 
                            local position = string.find(key,"New item");
                            if position then
                                table.insert(dict,val);
                            else
                                dict[key] = val
                            end
                        end
                    end
                end
            end
        elseif c == "/" then
            assert(label == "dict")
            return dict, j+1, j
        end
    
        i = j + 1
    end
end


function plistParse(s)
    local i, ni, tag, version, empty = 0
    local label = 0;
    while label ~= "plist" do
        ni, i, label, version = string.find(s, "<([%w:]+)(.-)>", i+1)
        assert(ni)
    end
    
    ni, i, _, label, empty = plistParser.nextTag(s, i)


    if empty == "/" then
        return {}
    elseif label == "dict" then
        return plistParser.dictionary(s, i+1)
    elseif label == "array" then
        return plistParser.array(s, i+1)
    end
end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值