一个 Chez Scheme 实现的轻量级非标准 XML 解析器 (青春版 XML 解析器)
- 将 XML 解析为 Scheme 树状结构
- XML 元素将被转换为
((name . attr-alist) . child-list)
的形式 - 可以在保留空白与忽略空白二者之间切换
- 目前只能忽略掉 XML 声明头(毕竟是青春版)
- 目前还不支持 DTD
- 标签中的注释目前还不能被正确解析
(注:需要预先安装 Chez Scheme (v9.5.8)。)
chez-xml 是一个单文件库,
./src/xml.sls
为源代码文件,
./src/xml.so
为其编译后文件,
只要二者之一在路径中,即可使用 chez-xml 库。
可以简单快捷地运行测例:
git clone https://github.com/Yunoinsky/xml-toml # 克隆仓库
cd chez-xml
scheme --script ./test/test.ss
为了在其他项目中使用 chez-xml,
我们可以将 xml.sls
或 xml.so
拷贝到对应项目中,
也可以选择全局安装。下面提供一种全局安装的方式
- 创建 ~~/Library/chezscheme/~ 目录
- 将
xml.so
拷贝到该目录 - 将 ~~/Library/chezscheme/~ 添加到环境变量
CHEZSCHEMELIBDIRS
中
我们节选了 Raysan 的杰出项目 raylib API 中的一小段作为样例
<?xml version="1.0" encoding="Windows-1252" ?>
<!-- ./test/test_raylibapi.xml -->
<!-- https://raw.githubusercontent.com/raysan5/raylib/master/parser/output/raylib_api.xml -->
<raylibAPI>
<Defines count="4">
<Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
<Define name="DEG2RAD" type="FLOAT_MATH" value="(PI/180.0f)" desc="" />
<Define name="RED" type="COLOR" value="CLITERAL(Color){ 200, 200, 200, 255 }" desc="Light Gray" />
<Define name="BLUE" type="COLOR" value="CLITERAL(Color){ 0, 121, 241, 255 }" desc="Blue" />
</Defines>
<Structs count="4">
<Struct name="Vector2" fieldCount="2" desc="Vector2, 2 components">
<Field type="float" name="x" desc="Vector x component" />
<Field type="float" name="y" desc="Vector y component" />
</Struct>
<Struct name="Vector3" fieldCount="3" desc="Vector3, 3 components">
<Field type="float" name="x" desc="Vector x component" />
<Field type="float" name="y" desc="Vector y component" />
<Field type="float" name="z" desc="Vector z component" />
</Struct>
<Struct name="Color" fieldCount="4" desc="Color, 4 components, R8G8B8A8 (32bit)">
<Field type="unsigned char" name="r" desc="Color red value" />
<Field type="unsigned char" name="g" desc="Color green value" />
<Field type="unsigned char" name="b" desc="Color blue value" />
<Field type="unsigned char" name="a" desc="Color alpha value" />
</Struct>
<Struct name="Rectangle" fieldCount="4" desc="Rectangle, 4 components">
<Field type="float" name="x" desc="Rectangle top-left corner position x" />
<Field type="float" name="y" desc="Rectangle top-left corner position y" />
<Field type="float" name="width" desc="Rectangle width" />
<Field type="float" name="height" desc="Rectangle height" />
</Struct>
</Structs>
<Functions count="2">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" />
<Param type="const char *" name="title" desc="" />
</Function>
<Function name="IsWindowReady" retType="bool" paramCount="0" desc="Check if window has been initialized successfully">
</Function>
</Functions>
</raylibAPI>
(load "./src/xml.so") ;; 如果已全局安装,可省略加载
(import (xml))
- (xml-load text-port preserve-blank)
-
从文本流加载 XML 数据,得到一个 scheme 。
如果参数 preserve-blank 为
#t
, 则所有空白字符都会被保留; 否则,则会被忽略。
(define fp (open-input-file "./test/test_raylibapi.xml"))
(define data (xml-load fp #f))
(pretty-print data)
- (xml-get-name node)
- 获取 XML 节点的名称
- (xml-get-attrs node)
- 获取 XML 节点的属性,以关联列表的形式
- (xml-get-children node)
- 获取 XML 节点的所有子项,以列表的形式
(define funcs-data (caddr (xml-get-eles data)))
(pretty-print (xml-get-name funcs-data))
(pretty-print (xml-get-attrs funcs-data))
(define func1-data (car (xml-get-eles funcs-data)))
(pretty-print (xml-get-name func1-data))
(pretty-print (xml-get-attrs func1-data))
(pretty-print (xml-get-eles func1-data))