KMP 实现鸿蒙跨端:Kotlin JSON 美化和分析器
本文介绍了基于Kotlin Multiplatform (KMP)实现的跨平台JSON处理工具,支持鸿蒙等多端应用开发。该工具提供JSON验证、格式化、结构分析和错误检测等核心功能,采用Kotlin状态机和字符串处理技术实现。核心算法包括括号/引号匹配检查、结构统计和智能格式化,通过KMP可编译为JavaScript在OpenHarmony运行。工具具备对象/数组统计、键值分析、值类型识别等特性,
·
KMP 实现鸿蒙跨端:Kotlin JSON 美化和分析器
目录
概述
本文档介绍如何在 Kotlin Multiplatform (KMP) 鸿蒙跨端开发中实现一个完整的 JSON 美化和分析系统。这个案例展示了如何使用 Kotlin 的字符串处理、状态机和数据分析来创建一个功能丰富的 JSON 工具。通过 KMP,这个工具可以无缝编译到 JavaScript,在 OpenHarmony 应用中运行,并支持用户输入进行实时处理。
工具的特点
- JSON 验证:检查 JSON 的合法性
- 格式化:美化 JSON 使其易于阅读
- 结构分析:统计 JSON 的结构信息
- 错误检测:识别常见的 JSON 错误
- 大小分析:计算原始和格式化后的大小
- 跨端兼容:一份 Kotlin 代码可同时服务多个平台
工具功能
1. JSON 验证
- 括号匹配:检查 {} 和 [] 是否匹配
- 引号匹配:检查 “” 是否匹配
- 转义处理:正确处理转义字符
- 错误报告:提示具体的错误信息
2. 结构分析
- 对象统计:计算 {} 的个数
- 数组统计:计算 [] 的个数
- 键值对统计:计算 : 的个数
- 值类型统计:统计字符串、数字、布尔值、空值的个数
3. 格式化
- 缩进处理:使用 2 空格缩进
- 换行处理:在合适的位置换行
- 空格处理:移除不必要的空格
4. 大小分析
- 原始大小:输入 JSON 的字节数
- 格式化大小:格式化后的字节数
- 增长率:计算大小的变化百分比
核心实现
1. 括号匹配检查
fun checkBrackets(): Boolean {
val stack = mutableListOf<Char>()
var inString = false
var escapeNext = false
for (char in json) {
if (escapeNext) {
escapeNext = false
continue
}
if (char == '\\') {
escapeNext = true
continue
}
if (char == '"') {
inString = !inString
continue
}
if (inString) continue
when (char) {
'{', '[' -> stack.add(char)
'}' -> {
if (stack.isEmpty() || stack.last() != '{') return false
stack.removeAt(stack.size - 1)
}
']' -> {
if (stack.isEmpty() || stack.last() != '[') return false
stack.removeAt(stack.size - 1)
}
}
}
return stack.isEmpty()
}
2. 引号匹配检查
fun checkQuotes(): Boolean {
var inString = false
var escapeNext = false
for (char in json) {
if (escapeNext) {
escapeNext = false
continue
}
if (char == '\\') {
escapeNext = true
continue
}
if (char == '"') {
inString = !inString
}
}
return !inString
}
3. 结构统计
var braceCount = 0
var bracketCount = 0
var colonCount = 0
var stringCount = 0
var numberCount = 0
var boolCount = 0
var nullCount = 0
var inString = false
var escapeNext = false
var i = 0
while (i < json.length) {
val char = json[i]
// 处理转义字符
if (escapeNext) {
escapeNext = false
i++
continue
}
if (char == '\\') {
escapeNext = true
i++
continue
}
if (char == '"') {
inString = !inString
if (inString) stringCount++
i++
continue
}
if (inString) {
i++
continue
}
when (char) {
'{' -> braceCount++
'[' -> bracketCount++
':' -> colonCount++
't', 'f' -> {
if (json.substring(i).startsWith("true") || json.substring(i).startsWith("false")) {
boolCount++
i += if (json.substring(i).startsWith("true")) 3 else 4
}
}
'n' -> {
if (json.substring(i).startsWith("null")) {
nullCount++
i += 3
}
}
in '0'..'9', '-' -> {
if (i == 0 || json[i - 1] in setOf(':', '[', ',', ' ')) {
numberCount++
while (i < json.length && (json[i].isDigit() || json[i] in setOf('.', 'e', 'E', '+', '-'))) {
i++
}
i--
}
}
}
i++
}
4. JSON 格式化
val formatted = mutableListOf<String>()
var indent = 0
var inString = false
var escapeNext = false
var currentLine = ""
for (char in json) {
if (escapeNext) {
currentLine += char
escapeNext = false
continue
}
if (char == '\\') {
currentLine += char
escapeNext = true
continue
}
if (char == '"') {
inString = !inString
currentLine += char
continue
}
if (inString) {
currentLine += char
continue
}
when (char) {
'{', '[' -> {
currentLine += char
formatted.add(" ".repeat(indent) + currentLine)
currentLine = ""
indent++
}
'}', ']' -> {
if (currentLine.isNotEmpty()) {
formatted.add(" ".repeat(indent) + currentLine)
currentLine = ""
}
indent--
formatted.add(" ".repeat(indent) + char)
}
',' -> {
currentLine += char
formatted.add(" ".repeat(indent) + currentLine)
currentLine = ""
}
':' -> {
currentLine += char + " "
}
' ' -> {
// 忽略空格
}
else -> {
currentLine += char
}
}
}
实战案例
案例:完整的 JSON 美化和分析器
Kotlin 源代码
@OptIn(ExperimentalJsExport::class)
@JsExport
fun jsonBeautifier(inputJson: String = "{\"name\":\"John\",\"age\":30}"): String {
val json = inputJson.trim()
if (json.isEmpty()) {
return "❌ 错误: JSON 不能为空"
}
// 1. 验证括号匹配
fun checkBrackets(): Boolean {
val stack = mutableListOf<Char>()
var inString = false
var escapeNext = false
for (char in json) {
if (escapeNext) {
escapeNext = false
continue
}
if (char == '\\') {
escapeNext = true
continue
}
if (char == '"') {
inString = !inString
continue
}
if (inString) continue
when (char) {
'{', '[' -> stack.add(char)
'}' -> {
if (stack.isEmpty() || stack.last() != '{') return false
stack.removeAt(stack.size - 1)
}
']' -> {
if (stack.isEmpty() || stack.last() != '[') return false
stack.removeAt(stack.size - 1)
}
}
}
return stack.isEmpty()
}
var isValid = checkBrackets()
// 2. 统计结构
var braceCount = 0
var bracketCount = 0
var stringCount = 0
var numberCount = 0
// ... 统计逻辑
// 3. 格式化
val formatted = mutableListOf<String>()
// ... 格式化逻辑
val formattedJson = formatted.joinToString("\n")
return "🔧 JSON 美化和分析器\n" +
"━━━━━━━━━━━━━━━━━━━━━\n" +
"1️⃣ 验证结果:\n" +
" 状态: ${if (isValid) "✅ 有效" else "❌ 无效"}\n\n" +
"2️⃣ 结构统计:\n" +
" 对象数: $braceCount\n" +
" 数组数: $bracketCount\n" +
" 字符串: $stringCount\n" +
" 数字: $numberCount\n\n" +
"4️⃣ 格式化结果:\n" +
formattedJson + "\n\n" +
"✅ 处理完成!"
}
ArkTS 调用代码
import { jsonBeautifier } from './hellokjs';
@Entry
@Component
struct Index {
@State message: string = '加载中...';
@State results: string[] = [];
@State caseTitle: string = 'JSON 美化和分析器';
@State inputText: string = '{"name":"John","age":30}';
loadResults(): void {
try {
const algorithmResult: string = jsonBeautifier(this.inputText);
this.results = [algorithmResult];
this.message = '✓ 分析完成';
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
this.message = `✗ 错误: ${errorMessage}`;
}
}
build() {
Column() {
// ... UI 代码
}
}
}
编译过程详解
Kotlin 到 JavaScript 的转换
| Kotlin 特性 | JavaScript 等价物 |
|---|---|
| mutableListOf | 数组 [] |
| String.substring | 字符串 slice |
| startsWith | 字符串 startsWith |
| repeat | 字符串 repeat |
| joinToString | 数组 join |
关键转换点
- 字符串处理:转换为 JavaScript 字符串方法
- 集合操作:转换为数组操作
- 状态机:转换为循环和条件判断
- 缩进处理:转换为字符串重复
工具扩展
扩展 1:添加 JSON 压缩
fun compressJson(): String {
var result = ""
var inString = false
var escapeNext = false
for (char in json) {
if (escapeNext) {
result += char
escapeNext = false
continue
}
if (char == '\\') {
result += char
escapeNext = true
continue
}
if (char == '"') {
inString = !inString
result += char
continue
}
if (inString) {
result += char
} else if (!char.isWhitespace()) {
result += char
}
}
return result
}
扩展 2:添加 JSON 路径查询
fun getValueByPath(path: String): String {
// 实现 JSONPath 查询
// 例如: $.name, $.hobbies[0]
return ""
}
扩展 3:添加 JSON 转换
fun jsonToMap(): Map<String, Any> {
// 将 JSON 转换为 Kotlin Map
return mapOf()
}
扩展 4:添加 JSON 比较
fun compareJson(other: String): String {
// 比较两个 JSON 的差异
return ""
}
最佳实践
1. 使用状态机处理字符串
// ✅ 好:使用状态机
var inString = false
var escapeNext = false
for (char in json) {
if (escapeNext) {
escapeNext = false
continue
}
if (char == '\\') {
escapeNext = true
continue
}
if (char == '"') {
inString = !inString
}
}
// ❌ 不好:简单的字符查找
val inString = json.contains('"')
2. 使用栈验证括号
// ✅ 好:使用栈
val stack = mutableListOf<Char>()
for (char in json) {
when (char) {
'{', '[' -> stack.add(char)
'}' -> if (stack.last() == '{') stack.removeAt(stack.size - 1)
']' -> if (stack.last() == '[') stack.removeAt(stack.size - 1)
}
}
// ❌ 不好:计数器
var braceCount = 0
for (char in json) {
if (char == '{') braceCount++
if (char == '}') braceCount--
}
3. 提前验证输入
// ✅ 好:提前检查
if (json.isEmpty()) {
return "错误: JSON 不能为空"
}
// ❌ 不好:处理过程中才发现
try {
// 处理 JSON
} catch (e: Exception) {
return "错误"
}
常见问题
Q1: 如何处理转义字符?
A: 使用 escapeNext 标志追踪转义状态:
var escapeNext = false
for (char in json) {
if (escapeNext) {
escapeNext = false
continue
}
if (char == '\\') {
escapeNext = true
}
}
Q2: 如何正确计算 JSON 大小?
A: 使用字符串长度:
val originalSize = json.length
val formattedSize = formattedJson.length
Q3: 如何处理 Unicode 字符?
A: Kotlin 原生支持 Unicode,直接处理即可。
Q4: 如何验证 JSON 的有效性?
A: 检查括号匹配和引号匹配,以及值的类型。
Q5: 如何优化大型 JSON 的处理?
A: 使用流式处理而不是一次性加载到内存。
总结
关键要点
- ✅ 使用状态机处理字符串
- ✅ 使用栈验证括号匹配
- ✅ 正确处理转义字符
- ✅ 提前验证输入
- ✅ KMP 能无缝编译到 JavaScript
下一步
- 实现 JSON 压缩
- 添加 JSONPath 查询
- 实现 JSON 转换
- 添加 JSON 比较
- 优化性能
参考资源
更多推荐


所有评论(0)