XML parser based on subhuti framework
npm install slime-xmlslime-xml 是一个使用 subhuti 解析器框架构建的严格模式 XML 解析器。它提供了完整的 XML 解析能力,包括元素、属性、文本、字符引用等完整支持,并可作为 WXML(微信小程序标记语言)解析器的基础。
subhuti 和 slime-ast 外无其他运行时依赖
bash
npm install slime-xml
`
快速开始
$3
`typescript
import XmlParser from 'slime-xml'
import XmlCstToAst from 'slime-xml/XmlCstToAst'
import XmlPrinter from 'slime-xml/XmlPrinter'
// 1. 解析 XML 字符串
const xml = 'Hello World '
const parser = new XmlParser(xml)
const cst = parser.Document()
// 2. 转换为 AST
const ast = XmlCstToAst.createDocumentAst(cst)
// 3. 打印 AST(验证 round-trip)
const output = XmlPrinter.print(ast)
console.log(output) // Hello World
`
$3
`typescript
const xml = ' '
const parser = new XmlParser(xml)
const cst = parser.Document()
const ast = XmlCstToAst.createDocumentAst(cst)
// AST 结构
// {
// type: 'XmlDocument',
// children: [{
// type: 'XmlElement',
// name: 'image',
// attributes: [
// { name: 'src', value: 'test.png' },
// { name: 'alt', value: 'test' }
// ],
// children: [],
// selfClosing: true
// }]
// }
`
$3
`typescript
const xml = 'Hello World '
const parser = new XmlParser(xml)
const cst = parser.Document()
const ast = XmlCstToAst.createDocumentAst(cst)
`
$3
`typescript
import XmlCharRef from 'slime-xml/XmlCharRef'
// 十进制字符引用
XmlCharRef.resolveDecCharRef('A') // 'A'
// 十六进制字符引用
XmlCharRef.resolveHexCharRef('A') // 'A'
// 预定义实体
XmlCharRef.resolveEntityRef('<') // '<'
XmlCharRef.resolveEntityRef('>') // '>'
XmlCharRef.resolveEntityRef('&') // '&'
XmlCharRef.resolveEntityRef('"') // '"'
XmlCharRef.resolveEntityRef(''') // "'"
// 转义文本
XmlCharRef.escapeText('Hello & ')
// 'Hello & <World>'
`
API 文档
$3
主解析器类,继承自 subhuti 的 SubhutiParser。
#### 方法
- Document() - 解析完整的 XML 文档,返回 CST
- Element() - 解析单个元素
- StartTag() - 解析开始标签
- EndTag() - 解析结束标签
- Attribute() - 解析属性
$3
CST 到 AST 的转换器。
#### 静态方法
- createDocumentAst(cst) - 将 Document CST 转换为 AST
- createElementAst(cst) - 将 Element CST 转换为 AST
- createAttributeAst(cst) - 将 Attribute CST 转换为 AST
- createTextAst(cst) - 将 Text CST 转换为 AST
$3
AST 打印器,将 AST 重新序列化为 XML 字符串。
#### 静态方法
- print(ast) - 打印完整的 XML 文档
- printElement(element) - 打印单个元素
- printAttribute(attr) - 打印属性
$3
字符引用处理工具。
#### 静态方法
- resolveDecCharRef(ref) - 解析十进制字符引用
- resolveHexCharRef(ref) - 解析十六进制字符引用
- resolveEntityRef(ref) - 解析预定义实体引用
- escapeText(text) - 转义文本中的特殊字符
$3
错误处理器,提供详细的错误诊断。
AST 结构
$3
`typescript
interface XmlDocument {
type: 'XmlDocument'
children: (XmlElement | XmlText | XmlComment | XmlCData)[]
}
`
$3
`typescript
interface XmlElement {
type: 'XmlElement'
name: string
attributes: XmlAttribute[]
children: (XmlElement | XmlText | XmlComment | XmlCData)[]
selfClosing: boolean
}
`
$3
`typescript
interface XmlAttribute {
type: 'XmlAttribute'
name: string
value: string | StringLiteral
}
`
$3
`typescript
interface XmlText {
type: 'XmlText'
value: string
}
`
开发
`bash
安装依赖
npm install
开发模式(监听文件变化)
npm run dev
构建
npm run build
运行测试
mono test/test-parser.ts
`
项目结构
`
slime-xml/
├── src/
│ ├── XmlParser.ts # 主解析器
│ ├── XmlTokens.ts # Token 定义
│ ├── XmlTokenType.ts # Token 类型
│ ├── XmlTokenConsumer.ts # Token 消费器
│ ├── XmlCharRef.ts # 字符引用处理
│ ├── XmlErrorHandler.ts # 错误处理
│ ├── XmlParseError.ts # 错误类型定义
│ ├── XmlPrinter.ts # AST 打印器
│ └── cstToAst/
│ ├── index.ts # CST → AST 入口
│ └── XmlCstToAst.ts # CST → AST 转换器
├── test/ # 测试文件
├── xmlgrammar/ # XML 语法规范文档
├── index.ts # 包入口
└── package.json
`
技术栈
- 解析器框架: subhuti
- AST 基础: slime-ast
- 构建工具: tsdown
- 语言: TypeScript 5.x
应用场景
$3
作为微信小程序 WXML 解析器的基础:
`typescript
// WXML 可以继承 XmlParser
class WxmlParser extends XmlParser {
// 扩展对 {{}} 插值的支持
}
`
$3
验证 XML 文档的结构:
`typescript
try {
const parser = new XmlParser(xmlString)
const cst = parser.Document()
console.log('XML 格式正确')
} catch (error) {
console.error('XML 解析错误:', error.message)
}
`
$3
格式化或美化 XML:
`typescript
const parser = new XmlParser(messyXml)
const cst = parser.Document()
const ast = XmlCstToAst.createDocumentAst(cst)
const formatted = XmlPrinter.print(ast) // 格式化的 XML
`
限制
- 严格模式: 仅支持 well-formed XML,不支持 HTML 的宽松解析
- DTD: 不支持 DTD 声明和验证
- 命名空间: 当前版本不支持 XML 命名空间
- 处理指令: 不支持 ` 等处理指令