lua解析xml总结

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

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

……

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

demo如下:

01 local xml = require("xmlSimple").newParser()
02  
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>'
24  
25  
26 local parsedXml = xml:ParseXmlText(testXml)
27  
28  
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
38  
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
44  
45 -- deep element test
46  
47 if parsedXml.testOne.testTwo.testFive.testFiveDeep.testFiveEvenDeeper.testSix['@someParam'] ~= "someValue" then error("Deep test error") end
48     
49 -- node functions test
50 local node = require("xmlSimple").newNode("testName")
51  
52 if node:name() ~= "testName" then error("Node creation failed") end
53  
54 node:setName("nameTest")
55 if node:name() ~= "nameTest" then error("Name function test failed") end
56  
57 node:setValue("valueTest")
58 if node:value() ~= "valueTest" then error("Value function test failed") end
59  
60 local childNode = require("xmlSimple").newNode("parent")
61  
62 node:addChild(childNode)
63  
64 if type(node:children()) ~= "table" then error("children function test failed") end
65 if #node:children() ~= 1 then error("AddChild function test failed") end
66 if node:numChildren() ~= 1 then error("numChildren function test failed") end
67  
68  
69 node:addProperty("name""value")
70  
71 if type(node:properties()) ~= "table" then error("properties function test failed") end
72 if #node:properties() ~= 1 then error("Add property function test failed") end
73 if node:numProperties() ~= 1 then error("Num properties function test failed") end
74  
75 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个标签和多个标签无法统一处理

格式一:

1 <DOCUMENT>
2 <item>
3 <key>北京</key>
4 </item>
5 </DOCUMENT>

格式二:

1 <DOCUMENT>
2 <item>
3 <key>北京</key>
4 </item>
5 <item>
6 <key>上海</key>
7 </item>
8 </DOCUMENT>

 

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

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

1 parsedXml.DOCUMENT.item.key

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

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

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

处理方法:

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

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

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


转载自http://www.xinghaixu.com/archives/980

猜你喜欢

转载自blog.csdn.net/pkorochi/article/details/51520440