类库大魔王
类库大魔王 多年C++、Go项目经验,长期从事跨平台(Windows/macOS/iOS/Android)应用架构设计与开发。

Lua中使用DOM读写XML


  在Lua神作《PIL》中操作XML的示例是用expat库的,众所周知expat是用类似SAX的接口的,这里介绍一下使用其他的库来实现DOM接口操作XML。
  可以使用的库有几个选择,包括ltxmlxercesrapidxml等等。ltxml使用TinyXMLTinyXPath提供的服务,xerces使用Xerces-C++提供的服务,而rapidxml则是使用RapidXML。这三个库我都有过一段时间的使用,不过都没怎么深入过。总的说来三个库各有特色,呃,其实是它们依赖的C/C++库的特点,ltxml我不是很喜欢,当初用的时候发现不知道为什么,同样一段代码执行多次后,打开并读取XML文档就会出错。于是后来转用xerces,它倒是基本让人满意,不过得附带一个Xerces-C++的DLL,感觉有点不爽,而且Xerces-C++应该说是比较完整的实现了XML的几个接口标准,但xerces只是封装了其中DOM读写的很小一部分接口。而rapidxml胜在运行速度飞快,从RapidXML的项目主页上可以看到一个简单的横向评测结果。xercesrapidxml的Lua接口非常相似,除了几个节点类型常量的名称和载入的表的名称不同外,其他的读写接口名称和签名几乎一模一样,它们的源代码可以在它们的项目主页上通过svn下载得到,但需要用户自己编译,当然也可以下载安装LuaPackLuaPack提供已经编译好的xercesrapidxml文件,但要注意的是由于使用VC2010进行编译,只能在Windows XP SP3或更高版本的Windows系统上运行。
  下面以rapidxml为例,简单演示一下如何操作XML文档。
  新建一个XML文档,并保存:

  require "rapidxml"
  local doc = rapidxml.parse( "" ) -- assign root node xml text
  local root = doc:root()
  for i = 1, 10 do
    local new_child = root:append( string.format( "test_node_%d", i ) ) -- create new child node
    new_child:set_attr( "index", tostring( i * 10 ) ) -- append new attribute named index with value i *10
    new_child:set_text( tostring( i * 20 ) ) -- set node text
  end
  doc:save( "C:\\testxml\\testdata.xml" , true )

  打开刚才创建并保存的XML文件,并读取:

  require "rapidxml"
  local doc = rapidxml.open( "C:\\testxml\\testdata.xml" )
  local root = doc:root()
  local child_nodes = root:children()
  for k, child_node in pairs( child_nodes ) do
    if child_node:type() == rapidxml.node_element then
      if child_node:exists_attr( "index" ) then
        print( child_node:name(), child_node:attribute( "index" ) ) -- 打印该节点的名称和index属性值
      end
      print( child_node:text() ) -- 打印该节点的文本内容
    end
  end

  比较方便的是,rapidxml把子节点集合用Lua table表示,所以可以方便地使用pairs等Lua的设施来进行操作。xerces的使用方法与上面的代码类似。

感觉本文不错,不妨小额鼓励我一下!
如果你有Visa、MasterCard之类的国际银行卡,也可以考虑以下选项:
如果你看不到评论框,说明Disqus被墙了。