现在的位置: 首页 > 编程语言 > lua > 正文
lua解析xml总结
2014年08月07日 lua, 编程语言 ⁄ 共 4399字 评论数 2 ⁄ 被围观 11,265 views+

lua解析xml有很多的第三方的库,例如:http://lua-users.org/wiki/LuaXml。但是每个库都有各自的优点和使用是否方便。

我一开始是打算使用luaXml库,在网上也找了很多的关于他的使用方法的blog。但是我觉得它很难用,遍历xml的时候,竟然是以数组下标的方式去进行访问,果断放弃。

……

经过N多库的下载和试用,最终我还是选择了Lua-Simple-XML-Parser

demo如下:

local xml = require("xmlSimple").newParser()

local testXml = '<testOne param="param1value">'
testXml = testXml .. '<testTwo paramTwo="param2value">'
testXml = testXml .. '<testThree>'
testXml = testXml .. 'testThreeValue'
testXml = testXml .. '</testThree>'
testXml = testXml .. '<testThree duplicate="one" duplicate="two">'
testXml = testXml .. 'testThreeValueTwo'
testXml = testXml .. '</testThree>'
testXml = testXml .. '<test_Four something="else">'
testXml = testXml .. 'testFourValue'
testXml = testXml .. '</test_Four>'
testXml = testXml .. '<testFive>'
testXml = testXml .. '<testFiveDeep>'
testXml = testXml .. '<testFiveEvenDeeper>'
testXml = testXml .. '<testSix someParam="someValue"/>'
testXml = testXml .. '</testFiveEvenDeeper>'
testXml = testXml .. '</testFiveDeep>'
testXml = testXml .. '</testFive>'
testXml = testXml .. 'testTwoValue'
testXml = testXml .. '</testTwo>'
testXml = testXml .. '</testOne>'


local parsedXml = xml:ParseXmlText(testXml)


if parsedXml.testOne == nil then error("Node not created") end
if parsedXml.testOne:name() ~= "testOne" then error("Node name not set") end
if parsedXml.testOne.testTwo == nil then error("Child node not created") end
if parsedXml.testOne.testTwo:name() ~= "testTwo" then error("Child node name not set") end
if parsedXml.testOne.testTwo:value() ~= "testTwoValue" then error("Node value not set") end
if parsedXml.testOne.testTwo.test_Four:value() ~= "testFourValue" then error("Second child node value not set") end
if parsedXml.testOne["@param"] ~= "param1value" then error("Parameter not set") end
if parsedXml.testOne.testTwo["@paramTwo"] ~= "param2value" then error("Second child node parameter not set") end
if parsedXml.testOne.testTwo.test_Four["@something"] ~= "else" then error("Deepest node parameter not set") end

-- duplicate names tests
if parsedXml.testOne.testTwo.testThree[1]:value() ~= "testThreeValue" then error("First of duplicate nodes value not set") end
if parsedXml.testOne.testTwo.testThree[2]:value() ~= "testThreeValueTwo" then error("Second of duplicate nodes value not set") end
if parsedXml.testOne.testTwo.testThree[2]["@duplicate"][1] ~= "one" then error("First of duplicate parameters not set") end
if parsedXml.testOne.testTwo.testThree[2]["@duplicate"][2] ~= "two" then error("Second of duplicate parameters not set") end

-- deep element test

if parsedXml.testOne.testTwo.testFive.testFiveDeep.testFiveEvenDeeper.testSix['@someParam'] ~= "someValue" then error("Deep test error") end
   
-- node functions test
local node = require("xmlSimple").newNode("testName")

if node:name() ~= "testName" then error("Node creation failed") end

node:setName("nameTest")
if node:name() ~= "nameTest" then error("Name function test failed") end

node:setValue("valueTest")
if node:value() ~= "valueTest" then error("Value function test failed") end

local childNode = require("xmlSimple").newNode("parent")

node:addChild(childNode)

if type(node:children()) ~= "table" then error("children function test failed") end
if #node:children() ~= 1 then error("AddChild function test failed") end
if node:numChildren() ~= 1 then error("numChildren function test failed") end


node:addProperty("name", "value")

if type(node:properties()) ~= "table" then error("properties function test failed") end
if #node:properties() ~= 1 then error("Add property function test failed") end
if node:numProperties() ~= 1 then error("Num properties function test failed") end

print("Tests passed")

看到demo,大家就可以知道,他是通过xml节点的名称遍历的,相当的方便。

备注:使用Lua-Simple-XML-Parser,请看demo中的使用,GitHub上的使用说明,感觉有点问题。

 

不过在使用过程中,还是踩到了两个坑,这里总结一下:

一、Lua-Simple-XML-Parser的取值函数value(),当你的xml中有节点的名称是<value></value>。会和库有冲突,在local parsedXml = xml:ParseXmlText(testXml)  这里会报错。

我比较笨的解决方法是:将testXml字符串中的 <value></value>全部替换成<myvalue></myvalue>。就是修改xml。当然对lua比较熟悉的,可以试着将这个库的value() 修改成其他的名称。

二、使用table.insert方法,提示insert无效

最后,使用google找了很久才发现,原来是因为我定义了一个string,名称就是"table",将全局的给覆盖掉了。而我的string没有insert这个方法。

踩得第二个坑,和Lua-Simple-XML-Parser库没有半点关系,只不过这个库里面使用了很多的table.insert这种方法。这里也一并总结下。以后即使写test测试的时候,变量也不能偷懒,随便的定义。

三、1个标签和多个标签无法统一处理

格式一:

<DOCUMENT>
<item>
<key>北京</key>
</item>
</DOCUMENT>

格式二:

<DOCUMENT>
<item>
<key>北京</key>
</item>
<item>
<key>上海</key>
</item>
</DOCUMENT>

 

上面的两种方式是没法进行统一的将item作为list,然后进行遍历的。

对于格式一:item这个标签只出现过一次的话,只能作为普通的属性。

parsedXml.DOCUMENT.item.key

对于格式二:item会被解析成为一个list。

local length = #parsedXml.DOCUMENT.item
for i=1,length do
    loacl value = parsedXml.DOCUMENT.item[i].key:value()
end

所以,当数据中item既有可能出现一次,也有可能出现多次的话,就比较麻烦了。

处理方法:

需要先判断的长度:local length = #parsedXml.DOCUMENT.item

当length = 0的时候,并且parsedXml.DOCUMENT.item ~= nil的时候,需要用parsedXml.DOCUMENT.item方式去取值。

当length > 0的时候,就可以for循环遍历了。

 

 

原创文章,转载请注明: 转载自成长的企鹅

本文链接地址: lua解析xml总结

关于我:成长的企鹅简介

目前有 2 条留言 其中:访客:1 条, 博主:0 条 引用: 1

  1. 校花等你来 : 2015年10月07日23:28:02  -49楼 @回复 回复

查看来自外部的引用: 1

给我留言

留言无头像?


×