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

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XML转换为Lua通常分为两个步骤:解析XML文件和生成Lua代码。 首先,要解析XML文件,可以使用LuaXML解析库,例如LuaExpat、LuaXMLluaxpath等。这些库可以帮助我们解析XML文件并将其转换为Lua中的数据结构。 其次,要生成Lua代码,可以根据XML的结构和内容,使用Lua的字符串拼接操作来生成Lua代码。根据XML的标签、属性和值的不同,可以采用不同的转换方式,例如创建Lua表、赋值、设置属性等。 以下是一个示例,演示了如何将XML转换为Lua: 假设我们有以下的XML文件example.xml: ``` <root> <person name="Alice" age="30" gender="female"> <interests> <interest>Sports</interest> <interest>Reading</interest> </interests> </person> <person name="Bob" age="35" gender="male"> <interests> <interest>Cooking</interest> <interest>Photography</interest> </interests> </person> </root> ``` 使用LuaXML库可以解析这个XML文件: ```lua local xml = require("LuaXML") local file = io.open("example.xml", "r") local data = file:read("*a") file:close() local x = xml.eval(data) local root = x:find("root") local persons = {} for i, person in ipairs(root:find("person")) do local p = {} p.name = person.attr.name p.age = tonumber(person.attr.age) p.gender = person.attr.gender p.interests = {} for i, interest in ipairs(person:find("interests")[1]:find("interest")) do table.insert(p.interests, interest:value()) end table.insert(persons, p) end ``` 上述代码将会生成一个名为`persons`的Lua表,其中包含了XML文件中所有的`person`节点的信息。可以通过访问`persons`表来获取这些节点的属性和值,以及`interests`子节点的内容。 需要注意的是,实际的XML结构可能更加复杂,因此在转换过程中可能需要添加更多的逻辑和处理步骤来满足具体的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值