lua解析xml有很多的第三方的库,例如:http://lua-users.org/wiki/LuaXml。但是每个库都有各自的优点和使用是否方便。
我一开始是打算使用luaXml库,在网上也找了很多的关于他的使用方法的blog。但是我觉得它很难用,遍历xml的时候,竟然是以数组下标的方式去进行访问,果断放弃。
……
经过N多库的下载和试用,最终我还是选择了Lua-Simple-XML-Parser。
demo如下:
01 |
local xml = require( "xmlSimple" ).newParser() |
03 |
local testXml = '<testOne param="param1value">' |
04 |
testXml = testXml .. '<testTwo paramTwo="param2value">' |
05 |
testXml = testXml .. '<testThree>' |
06 |
testXml = testXml .. 'testThreeValue' |
07 |
testXml = testXml .. '</testThree>' |
08 |
testXml = testXml .. '<testThree duplicate="one" duplicate="two">' |
09 |
testXml = testXml .. 'testThreeValueTwo' |
10 |
testXml = testXml .. '</testThree>' |
11 |
testXml = testXml .. '<test_Four something="else">' |
12 |
testXml = testXml .. 'testFourValue' |
13 |
testXml = testXml .. '</test_Four>' |
14 |
testXml = testXml .. '<testFive>' |
15 |
testXml = testXml .. '<testFiveDeep>' |
16 |
testXml = testXml .. '<testFiveEvenDeeper>' |
17 |
testXml = testXml .. '<testSix someParam="someValue"/>' |
18 |
testXml = testXml .. '</testFiveEvenDeeper>' |
19 |
testXml = testXml .. '</testFiveDeep>' |
20 |
testXml = testXml .. '</testFive>' |
21 |
testXml = testXml .. 'testTwoValue' |
22 |
testXml = testXml .. '</testTwo>' |
23 |
testXml = testXml .. '</testOne>' |
26 |
local parsedXml = xml:ParseXmlText(testXml) |
29 |
if parsedXml.testOne = = nil then error( "Node not created" ) end |
30 |
if parsedXml.testOne:name() ~ = "testOne" then error( "Node name not set" ) end |
31 |
if parsedXml.testOne.testTwo = = nil then error( "Child node not created" ) end |
32 |
if parsedXml.testOne.testTwo:name() ~ = "testTwo" then error( "Child node name not set" ) end |
33 |
if parsedXml.testOne.testTwo:value() ~ = "testTwoValue" then error( "Node value not set" ) end |
34 |
if parsedXml.testOne.testTwo.test_Four:value() ~ = "testFourValue" then error( "Second child node value not set" ) end |
35 |
if parsedXml.testOne[ "@param" ] ~ = "param1value" then error( "Parameter not set" ) end |
36 |
if parsedXml.testOne.testTwo[ "@paramTwo" ] ~ = "param2value" then error( "Second child node parameter not set" ) end |
37 |
if parsedXml.testOne.testTwo.test_Four[ "@something" ] ~ = "else" then error( "Deepest node parameter not set" ) end |
39 |
- - duplicate names tests |
40 |
if parsedXml.testOne.testTwo.testThree[ 1 ]:value() ~ = "testThreeValue" then error( "First of duplicate nodes value not set" ) end |
41 |
if parsedXml.testOne.testTwo.testThree[ 2 ]:value() ~ = "testThreeValueTwo" then error( "Second of duplicate nodes value not set" ) end |
42 |
if parsedXml.testOne.testTwo.testThree[ 2 ][ "@duplicate" ][ 1 ] ~ = "one" then error( "First of duplicate parameters not set" ) end |
43 |
if parsedXml.testOne.testTwo.testThree[ 2 ][ "@duplicate" ][ 2 ] ~ = "two" then error( "Second of duplicate parameters not set" ) end |
47 |
if parsedXml.testOne.testTwo.testFive.testFiveDeep.testFiveEvenDeeper.testSix[ '@someParam' ] ~ = "someValue" then error( "Deep test error" ) end |
49 |
- - node functions test |
50 |
local node = require( "xmlSimple" ).newNode( "testName" ) |
52 |
if node:name() ~ = "testName" then error( "Node creation failed" ) end |
54 |
node:setName( "nameTest" ) |
55 |
if node:name() ~ = "nameTest" then error( "Name function test failed" ) end |
57 |
node:setValue( "valueTest" ) |
58 |
if node:value() ~ = "valueTest" then error( "Value function test failed" ) end |
60 |
local childNode = require( "xmlSimple" ).newNode( "parent" ) |
62 |
node:addChild(childNode) |
64 |
if type (node:children()) ~ = "table" then error( "children function test failed" ) end |
66 |
if node:numChildren() ~ = 1 then error( "numChildren function test failed" ) end |
69 |
node:addProperty( "name" , "value" ) |
71 |
if type (node:properties()) ~ = "table" then error( "properties function test failed" ) end |
73 |
if node:numProperties() ~ = 1 then error( "Num properties function test failed" ) end |
看到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个标签和多个标签无法统一处理
格式一:
格式二:
上面的两种方式是没法进行统一的将item作为list,然后进行遍历的。
对于格式一:item这个标签只出现过一次的话,只能作为普通的属性。
1 |
parsedXml.DOCUMENT.item.key |
对于格式二:item会被解析成为一个list。
3 |
loacl value = parsedXml.DOCUMENT.item[i].key:value() |
所以,当数据中item既有可能出现一次,也有可能出现多次的话,就比较麻烦了。
处理方法:
需要先判断的长度:local length = #parsedXml.DOCUMENT.item
当length = 0的时候,并且parsedXml.DOCUMENT.item ~= nil的时候,需要用parsedXml.DOCUMENT.item方式去取值。
当length > 0的时候,就可以for循环遍历了。
转载自http://www.xinghaixu.com/archives/980