ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

kaml YamlNode完全指南:如何不写data class也能灵活解析任意YAML文档

kaml YamlNode完全指南:如何不写data class也能灵活解析任意YAML文档 kaml YamlNode完全指南如何不写data class也能灵活解析任意YAML文档【免费下载链接】kamlYAML support for kotlinx.serialization项目地址: https://gitcode.com/gh_mirrors/ka/kamlkaml是 Kotlin 生态中为 kotlinx.serialization 提供 YAML 支持的序列化库。当 YAML 文档结构未知、字段经常变化、或者你只是需要读取其中几个值时不必为每种结构都定义一个 data class——kaml 的YamlNode可以把任意 YAML 文档解析成一棵可自由遍历的节点树让数据按需读取。为什么需要 YamlNode 这种动态解析方式通常用 kotlinx.serialization 读取数据要先声明一个Serializable的 data class字段名、类型、结构必须与文档一一对应。这在内部配置文件中没问题但面对以下场景就很尴尬 解析第三方或用户自定义的 YAML 文件结构事先无法确定 只需从大文档里提取个别字段不想为整棵树建模 做校验、转换、工具类功能需要逐节点检查原始内容⚡ 文档结构经常变化每次改动都要改类定义YamlNode 正是为这些场景设计的先原样收下整个文档再按路径逐层访问取到哪个值就转成什么类型。一行代码把 YAML 字符串解析成 YamlNodekaml 的入口是Yaml类其中的parseToYamlNode方法定义在src/commonMain/kotlin/com/charleskorn/kaml/Yaml.kt第 75 行附近可直接把字符串或输入流解析为根节点val input leader: Amy members: - Bob - Cindy - Dan val root Yaml.default.parseToYamlNode(input)此时root就是整棵 YAML 文档的节点树。JVM 平台上还可以直接传入InputStream方便读取文件。认识 YamlNode 家族的 5 种节点YamlNode是一个密封类sealed class所有子类型集中定义在src/commonMain/kotlin/com/charleskorn/kaml/YamlNode.kt中与 YAML 1.2 规范的核心结构一一对应节点类型对应 YAML 内容关键属性YamlScalar标量字符串、数字、布尔等content原始字符串值YamlNullnull或空值无YamlList序列-开头的列表items: ListYamlNodeYamlMap映射键值对entries: MapYamlScalar, YamlNodeYamlTaggedNode带!tag标签的节点tag与innerNode每个节点还都带有pathYamlPath类型属性记录它在原始文档中的位置和路径这一点后面讲错误处理时会用到。如何取出嵌套字段类型转换扩展属性拿到节点后kaml 提供了一组扩展属性帮你安全地向下钻取YamlNode.kt第 299-312 行// 取 members 列表的第 2 个元素 val name: String root.yamlMap .getYamlList(members)!![1] .yamlScalar .content // Cindy可用的扩展属性包括yamlScalar、yamlNull、yamlList、yamlMap、yamlTaggedNode。它们不是简单的强转——类型不匹配时会抛出带清晰信息的IncorrectTypeException例如 Expected element to be YamlScalar but is YamlMap并附带节点的路径比直接ClassCastException好排查得多。YamlMap还提供了更方便的访问方式YamlNode.kt第 226-244 行map.getYamlList(members)按类型取键值键不存在返回nullmap.getScalar(name)专门取标量值map[key]这类操作符让遍历代码更贴近普通 Map 的写法YamlScalar 内置的类型转换方法数字、布尔、字符一次搞定标量节点的content是字符串但YamlScalar内置了完整的类型转换 APIYamlNode.kt第 41-122 行无需手写toInt()、toBoolean()之类的解析逻辑整数类toByte()/toShort()/toInt()/toLong()并自动支持0x十六进制、0o八进制前缀浮点类toFloat()/toDouble()正确识别 YAML 1.2 的.inf、.nan等特殊值布尔类toBoolean()接受true/True/TRUE等 YAML 规范写法字符类toChar()转换失败时统一抛出YamlScalarFormatException错误信息会标明该值不是合法的某某类型及其位置。出错不可怕用 path 精准定位问题节点使用 YamlNode 做动态解析最常见的痛点是文档某个地方不符合预期时我在哪一步挂的kaml 的答案是每个节点都携带YamlPath。YamlPath定义于src/commonMain/kotlin/com/charleskorn/kaml/YamlPath.kt由若干路径段组成记录从根节点到当前节点走过的每一步——映射键、列表下标、别名引用等。它还能通过toHumanReadableString()生成类似.members[1].name的可读路径配合节点自身的location行列号属性你可以轻松向用户报告第几行第几列、哪个键的值有问题。kaml 内置的异常家族src/commonMain/kotlin/com/charleskorn/kaml/YamlException.kt几乎都携带path常用速查异常触发场景YamlScalarFormatException标量值无法转成目标类型IncorrectTypeException节点实际类型与期望类型不符DuplicateKeyException同一层映射出现重复键MalformedYamlExceptionYAML 语法本身不合法EmptyYamlDocumentException文档为空YamlNode 还能和 data class 互通吗可以。YamlNode本身标注了Serializable由YamlNodeSerializer负责这意味着它既可以先动态解析、挑选出你关心的子树再把子树编码回 YAML 字符串也可以把处理后的节点作为Map、List等标准集合结构的一部分参与序列化。典型的先探查、后处理工作流就是parseToYamlNode原样接收文档用扩展属性逐层校验结构、提取关键子树对子树做转换后再按需交给 kotlinx.serialization 编码输出上手建议与小贴士✅ 结构固定的内部配置优先定义 data class让编译器帮你把关✅ 结构未知或只取部分字段用 YamlNode 动态遍历✅ 访问节点前先判断类型或用get系列方法避免裸用扩展属性✅ 抛异常时把path打印出来定位问题事半功倍⚠️ 注意kaml 官方已宣布停止主动维护README 中说明项目已归档源码与已发布版本仍可用长期项目可关注社区维护的分支或替代方案总结kaml 的 YamlNode 让你不写 data class 也能优雅解析任意 YAML 文档一行parseToYamlNode得到节点树5 种子类型覆盖全部 YAML 结构扩展属性 类型化get让字段访问安全直白YamlScalar内置转换和YamlPath位置追踪则补齐了动态解析最缺的类型安全与可调试性两块拼图。核心源码集中在 YamlNode.kt、Yaml.kt、YamlPath.kt 与 YamlException.kt配合src/commonTest/kotlin/com/charleskorn/kaml/YamlNodeTest.kt中的测试用例可以快速验证各种取值行为。【免费下载链接】kamlYAML support for kotlinx.serialization项目地址: https://gitcode.com/gh_mirrors/ka/kaml创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表