跳转到内容

core.base.xml

此模块提供了一个轻量级的 DOM 风格 XML 工具包,可在 Xmake 的沙箱环境中工作。它专注于可预测的数据结构、类似 JSON 的易用性,以及可选的流式解析,使您可以在不构建整个树的情况下解析大型 XML 文档。

提示

使用此模块需要先导入:import("core.base.xml")

XML 模块特性:

  • 使用普通 Lua 表的 DOM 风格节点结构
  • 用于大文件的流式解析器(xml.scan
  • 类似 XPath 的查询(xml.find
  • 便捷的文件 I/O 辅助函数(xml.loadfilexml.savefile
  • 支持注释、CDATA、DOCTYPE 和未引用的属性
  • 可自定义缩进的格式化输出

XML 节点是具有以下结构的普通 Lua 表:

lua
{
    name     = "element-name" | nil,  -- 仅用于元素节点
    kind     = "element" | "text" | "comment" | "cdata" | "doctype" | "document",
    attrs    = { key = value, ... } or nil,
    text     = string or nil,
    children = { child1, child2, ... } or nil,
    prolog   = { comment/doctype nodes before root } or nil
}

xml.decode

  • 解析 XML 字符串为文档节点

函数原型

API

lua
xml.decode(xml_string: <string>, options?: <table>)

参数说明

参数描述
xml_string要解析的 XML 字符串
options可选的解析选项表

选项

选项描述
trim_text = true去除文本节点中的前导/尾随空格
keep_whitespace_nodes = true保留仅包含空白字符的文本节点

返回值说明

类型描述
table文档节点(XML 树的根)

用法说明

lua
import("core.base.xml")

local doc = assert(xml.decode([[
<?xml version="1.0"?>
<root id="1">
  <item id="foo">hello</item>
</root>
]]))

xml.encode

  • 将文档节点编码为 XML 字符串

函数原型

API

lua
xml.encode(doc: <table>, options?: <table>)

参数说明

参数描述
doc要编码的文档节点
options可选的编码选项表

选项

选项描述
pretty = true启用格式化输出
indent缩进的空格数(默认:2)
indentchar用于缩进的字符(默认:" ")

返回值说明

类型描述
stringXML 字符串表示

用法说明

lua
import("core.base.xml")

local doc = xml.decode("<root><item>hello</item></root>")
local pretty = assert(xml.encode(doc, {pretty = true, indent = 2}))

xml.loadfile

  • 从文件加载 XML 文档

函数原型

API

lua
xml.loadfile(filepath: <string>, options?: <table>)

参数说明

参数描述
filepathXML 文件路径
options可选的解析选项表(与 xml.decode 相同)

返回值说明

类型描述
table文档节点

用法说明

lua
import("core.base.xml")

local plist = assert(xml.loadfile("Info.plist"))

xml.savefile

  • 将 XML 文档保存到文件

函数原型

API

lua
xml.savefile(filepath: <string>, doc: <table>, options?: <table>)

参数说明

参数描述
filepath保存 XML 文件的路径
doc要保存的文档节点
options可选的编码选项表(与 xml.encode 相同)

返回值说明

类型描述
boolean成功返回 true

用法说明

lua
import("core.base.xml")

local doc = xml.loadfile("Info.plist")
-- ... 修改节点 ...
assert(xml.savefile("Info.plist", doc, {pretty = true, indent = 2}))

xml.find

  • 使用类似 XPath 的查询查找节点

函数原型

API

lua
xml.find(doc: <table>, xpath: <string>)

参数说明

参数描述
doc文档节点或要搜索的任意节点
xpath类似 XPath 的查询字符串

返回值说明

类型描述
table|nil找到的节点,如果未找到则返回 nil

用法说明

lua
import("core.base.xml")

local doc = assert(xml.loadfile("config.xml"))

-- 通过路径查找
local element = xml.find(doc, "/root/item")

-- 通过属性查找
local item = xml.find(doc, "//item[@id='foo']")

-- 通过文本内容查找
local node = xml.find(doc, "//string[text()='value']")

xml.scan

  • 流式解析 XML 并为每个节点调用回调函数

函数原型

API

lua
xml.scan(xml_string: <string>, callback: <function>, options?: <table>)

参数说明

参数描述
xml_string要解析的 XML 字符串
callback为每个节点调用的函数:function(node) -> boolean
options可选的解析选项表(与 xml.decode 相同)

回调返回值

从回调函数返回 false 会立即停止扫描。

用法说明

lua
import("core.base.xml")

local found
xml.scan(plist_text, function(node)
    if node.name == "key" and xml.text_of(node) == "NSPrincipalClass" then
        found = node
        return false -- 提前终止
    end
end)

xml.scan 在节点完成时遍历它们;返回 false 会立即停止扫描。这对于只需要几个条目的大文件非常理想。

xml.text_of

  • 获取节点的文本内容

函数原型

API

lua
xml.text_of(node: <table>)

参数说明

参数描述
node要提取文本的节点

返回值说明

类型描述
string节点的文本内容

用法说明

lua
import("core.base.xml")

local node = xml.find(doc, "//item[@id='foo']")
local text = xml.text_of(node)  -- 返回 "hello"

xml.text

  • 创建文本节点

函数原型

API

lua
xml.text(text: <string>)

参数说明

参数描述
text文本内容

返回值说明

类型描述
table文本节点

用法说明

lua
import("core.base.xml")

local textnode = xml.text("hello")

xml.empty

  • 创建空元素节点

函数原型

API

lua
xml.empty(name: <string>, attrs?: <table>)

参数说明

参数描述
name元素名称
attrs可选的属性表

返回值说明

类型描述
table元素节点

用法说明

lua
import("core.base.xml")

local empty = xml.empty("br", {class = "line"})

xml.comment

  • 创建注释节点

函数原型

API

lua
xml.comment(text: <string>)

参数说明

参数描述
text注释文本

返回值说明

类型描述
table注释节点

用法说明

lua
import("core.base.xml")

local comment = xml.comment("generated by xmake")

xml.cdata

  • 创建 CDATA 节点

函数原型

API

lua
xml.cdata(text: <string>)

参数说明

参数描述
textCDATA 文本

返回值说明

类型描述
tableCDATA 节点

用法说明

lua
import("core.base.xml")

local cdata_node = xml.cdata("if (value < 1) {...}")

xml.doctype

  • 创建 DOCTYPE 节点

函数原型

API

lua
xml.doctype(declaration: <string>)

参数说明

参数描述
declarationDOCTYPE 声明字符串

返回值说明

类型描述
tableDOCTYPE 节点

用法说明

lua
import("core.base.xml")

local doctype = xml.doctype('plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"')

完整示例

lua
import("core.base.xml")

-- 解析 XML 字符串
local doc = assert(xml.decode([[
<?xml version="1.0"?>
<root id="1">
  <item id="foo">hello</item>
</root>
]]))

-- 查找并修改节点
local item = assert(xml.find(doc, "//item[@id='foo']"))
item.attrs.lang = "en"             -- 直接修改属性
item.children = {xml.text("world")} -- 替换现有文本节点

-- 添加注释
table.insert(doc.children, xml.comment("generated by xmake"))

-- 使用格式化输出编码
local pretty = assert(xml.encode(doc, {pretty = true}))
assert(xml.savefile("out.xml", doc, {pretty = true}))