您的位置:首页 > 移动开发 > Cocos引擎

cocos2d lua集成XML教程

2014-08-19 16:09 351 查看


</pre>Installation</h1><ol class="task-list" style="padding:0px 0px 0px 2em; margin-top:0px; margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif; font-size:16px; line-height:25.600000381469727px"><li style="">Copy the xmlSimple.lua file to your project.</li><li style="">Create a local variable <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px">local xml = require("xmlSimple.lua").newParser()</code></li><li style="">Read xml using <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px">xml:ParseXmlText(xmlString)</code> or <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; padding:0.2em 0px; margin:0px">xml:loadFile(xmlFilename, base)</code></li></ol><h1 style="font-size:2.25em; margin:1em 0px 16px; line-height:1.2; position:relative; padding-bottom:0.3em; border-bottom-width:1px; border-bottom-style:solid; border-bottom-color:rgb(238,238,238); color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif"><a target=_blank target="_blank" name="user-content-parsing-xml" class="anchor" href="https://github.com/Cluain/Lua-Simple-XML-Parser#parsing-xml" style="color:rgb(65,131,196); text-decoration:none; position:absolute; top:0px; bottom:0px; left:0px; display:block; padding-right:6px; padding-left:30px; margin-left:-30px; background:transparent"></a>Parsing XML</h1><div class="highlight highlight-xml" style="margin-bottom:16px; color:rgb(51,51,51); font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif; font-size:16px; line-height:25.600000381469727px"><pre style="overflow:auto; font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace; font-size:14px; margin-top:0px; margin-bottom:0px; padding:16px; line-height:1.45; word-wrap:normal; word-break:normal; background-color:rgb(247,247,247)"><span class="nt" style="color:navy"><test</span> <span class="na" style="color:teal">one=</span><span class="s" style="color:rgb(221,17,68)">"two"</span><span class="nt" style="color:navy">></span>
<span class="nt" style="color:navy"><three</span> <span class="na" style="color:teal">four=</span><span class="s" style="color:rgb(221,17,68)">"five"</span> <span class="na" style="color:teal">four=</span><span class="s" style="color:rgb(221,17,68)">"six"</span><span class="nt" style="color:navy">/></span>
<span class="nt" style="color:navy"><three></span>eight<span class="nt" style="color:navy"></three></span>
<span class="nt" style="color:navy"><nine</span> <span class="na" style="color:teal">ten=</span><span class="s" style="color:rgb(221,17,68)">"eleven"</span><span class="nt" style="color:navy">></span>twelve<span class="nt" style="color:navy"></nine></span>
<span class="nt" style="color:navy"></test></span>


You can access values in two ways:

Using the simple method:

xml.test["@one"] == "two"
xml.test.nine["@ten"] == "eleven"
xml.test.nine:value() == "twelve"
xml.test.three[1]["@four"][1] == "five"
xml.test.three[1]["@four"][2] == "six"
xml.test.three[2]:value() == "eight"


or if your XML is a little bit more complicated you can do it like this:

xml:children()[1]:name() == "test"
xml:children()[1]:children()[2]:value() == "eight"
xml:properties()[1] == {name = "one", value = "two"}



Limitations

There's no support for namespaces. When I see namespaces I immediately start to remember days when I worked at corporate. We had to use namespaces only because XML was so convoluted we would not be able to handle it without them. In the end XML parsing took
longer for some APIs then actual logic of the API. If you're in this situation it is better to step back and do something about it rather than asking for namespace support. I am using this module to read fairly simple XML. Even if it is a large XML string,
the structure is still simple, so I was not able to test it properly. Please create a new Issue if you spot a problem. Please take a loook at xmlTest.lua for an example of use.


Final
notes

This is a modified version of Corona-XML-Module by Jonathan Beebe which in turn is based
on Alexander Makeev's Lua-only XML parser found here


xmlSimple.lua 的代码

module(..., package.seeall)

---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
--
-- xml.lua - XML parser for use with the Corona SDK.
--
-- version: 1.2
--
-- CHANGELOG:
--
-- 1.2 - Created new structure for returned table
-- 1.1 - Fixed base directory issue with the loadFile() function.
--
-- NOTE: This is a modified version of Alexander Makeev's Lua-only XML parser
-- found here: http://lua-users.org/wiki/LuaXml --
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
function newParser()

XmlParser = {};

function XmlParser:ToXmlString(value)
value = string.gsub(value, "&", "&"); -- '&' -> "&"
value = string.gsub(value, "<", "<"); -- '<' -> "<"
value = string.gsub(value, ">", ">"); -- '>' -> ">"
value = string.gsub(value, "\"", """); -- '"' -> """
value = string.gsub(value, "([^%w%&%;%p%\t% ])",
function(c)
return string.format("&#x%X;", string.byte(c))
end);
return value;
end

function XmlParser:FromXmlString(value)
value = string.gsub(value, "&#x([%x]+)%;",
function(h)
return string.char(tonumber(h, 16))
end);
value = string.gsub(value, "&#([0-9]+)%;",
function(h)
return string.char(tonumber(h, 10))
end);
value = string.gsub(value, """, "\"");
value = string.gsub(value, "'", "'");
value = string.gsub(value, ">", ">");
value = string.gsub(value, "<", "<");
value = string.gsub(value, "&", "&");
return value;
end

function XmlParser:ParseArgs(node, s)
string.gsub(s, "([%w_]+)%s*=%s*([\"'])(.-)%2", function(w, _, a)
node:addProperty(w, self:FromXmlString(a))
end)
end

function XmlParser:ParseXmlText(xmlText)
local stack = {}
local top = newNode()
table.insert(stack, top)
local ni, c, label, xarg, empty
local i, j = 1, 1
while true do
ni, j, c, label, xarg, empty = string.find(xmlText, "<(%/?)([%w_:]+)(.-)(%/?)>", i)
if not ni then break end
local text = string.sub(xmlText, i, ni - 1);
if not string.find(text, "^%s*$") then
local lVal = (top:value() or "") .. self:FromXmlString(text)
stack[#stack]:setValue(lVal)
end
if empty == "/" then -- empty element tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
top:addChild(lNode)
elseif c == "" then -- start tag
local lNode = newNode(label)
self:ParseArgs(lNode, xarg)
table.insert(stack, lNode)
top = lNode
else -- end tag
local toclose = table.remove(stack) -- remove top

top = stack[#stack]
if #stack < 1 then
error("XmlParser: nothing to close with " .. label)
end
if toclose:name() ~= label then
error("XmlParser: trying to close " .. toclose.name .. " with " .. label)
end
top:addChild(toclose)
end
i = j + 1
end
local text = string.sub(xmlText, i);
if #stack > 1 then
error("XmlParser: unclosed " .. stack[#stack]:name())
end
return top
end

function XmlParser:loadFile(xmlFilename, base)
if not xmlFilename then
return nil;
end

base = base or "";
path = base .. xmlFilename;

local hFile, err = io.open(path, "r");

if hFile and not err then
local xmlText = hFile:read("*all"); -- read file content
io.close(hFile);
return self:ParseXmlText(xmlText), nil;
else
print(err)
return nil
end
end

return XmlParser
end

function newNode(name)
local node = {}
node.___value = nil
node.___name = name
node.___children = {}
node.___props = {}

function node:value() return self.___value end
function node:setValue(val) self.___value = val end
function node:name() return self.___name end
function node:setName(name) self.___name = name end
function node:children() return self.___children end
function node:numChildren() return #self.___children end
function node:addChild(child)
if self[child:name()] ~= nil then
if type(self[child:name()].name) == "function" then
local tempTable = {}
table.insert(tempTable, self[child:name()])
self[child:name()] = tempTable
end
table.insert(self[child:name()], child)
else
self[child:name()] = child
end
table.insert(self.___children, child)
end

function node:properties() return self.___props end
function node:numProperties() return #self.___props end
function node:addProperty(name, value)
local lName = "@" .. name
if self[lName] ~= nil then
if type(self[lName]) == "string" then
local tempTable = {}
table.insert(tempTable, self[lName])
self[lName] = tempTable
end
table.insert(self[lName], value)
else
self[lName] = value
end
table.insert(self.___props, { name = name, value = self[name] })
end

return node
end


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: