KMP OpenHarmony JSON处理和数据转换工具
JSON处理工具实现摘要: 本文介绍了基于KMP框架的JSON处理工具实现方案,包含五大核心功能:JSON验证与错误定位、格式化美化、压缩优化、数据转换映射以及合并路径查询。工具采用Kotlin跨平台开发,支持OpenHarmony平台调用。重点展示了JSON验证功能的实现细节,通过栈结构检测括号匹配和字符串闭合状态,提供精确的错误位置信息。该工具可广泛应用于API开发、数据处理、配置管理等场景,

文章概述
JSON(JavaScript Object Notation)已经成为现代应用开发中最重要的数据交换格式。无论是Web API、移动应用还是微服务架构,JSON都扮演着核心角色。然而,在实际开发中,开发者经常需要处理复杂的JSON数据、进行深层次的数据转换、验证JSON的有效性、以及对JSON进行美化和压缩等操作。这就需要一套功能完整、性能高效的JSON处理工具。
JSON处理和数据转换工具在实际应用中有广泛的用途。在API开发中,需要验证请求和响应的JSON格式。在数据处理中,需要对JSON进行格式化、美化和压缩。在配置管理中,需要验证配置文件的有效性并进行转换。在日志分析中,需要解析和格式化JSON日志。在数据迁移中,需要转换和验证JSON数据。在前后端交互中,需要进行复杂的数据转换和映射。
本文将深入探讨如何在KMP(Kotlin Multiplatform)框架下实现一套完整的JSON处理和数据转换工具,并展示如何在OpenHarmony鸿蒙平台上进行跨端调用。我们将提供多种JSON处理功能,包括验证、格式化、压缩、转换、合并、路径查询等,帮助开发者高效处理JSON数据。
工具功能详解
核心功能
功能1:JSON验证和错误定位(JSON Validation and Error Localization)
验证JSON字符串是否符合JSON规范,并精确定位错误位置。这是最基础的功能,用于检查JSON的有效性。
功能特点:
- 检查JSON语法是否正确
- 提供详细的错误信息和位置
- 支持嵌套结构验证
- 高效的验证算法
- 返回错误行列号
功能2:JSON格式化和美化(JSON Formatting and Pretty Printing)
将JSON字符串格式化为可读的形式,包括缩进和换行。这对于调试和阅读JSON数据非常重要。
功能特点:
- 自定义缩进大小
- 支持多种缩进方式(空格或制表符)
- 保留原有的数据结构
- 性能优化
- 支持排序键值
功能3:JSON压缩和优化(JSON Minification and Optimization)
将JSON字符串压缩为最小形式,移除所有不必要的空白字符。这对于减少网络传输大小很有帮助。
功能特点:
- 移除所有空白字符
- 保留数据完整性
- 快速压缩算法
- 支持大型JSON文件
- 计算压缩率
功能4:JSON数据转换和映射(JSON Transformation and Mapping)
在JSON和其他格式之间进行转换,如JSON到Map、JSON到对象、JSON到CSV等。
功能特点:
- 支持多种转换格式
- 灵活的转换选项
- 类型安全的转换
- 错误处理机制
- 支持自定义转换规则
功能5:JSON合并和路径查询(JSON Merging and Path Query)
合并多个JSON对象,使用路径表达式查询JSON中的特定值。这对于处理复杂的嵌套JSON结构很有用。
功能特点:
- 支持深度合并
- 支持点号和括号表示法
- 支持数组索引
- 支持通配符
- 高效的查询算法
Kotlin实现
完整的Kotlin代码实现
/**
* JSON处理和数据转换工具 - KMP OpenHarmony
* 提供JSON处理的多种功能
*/
object JSONToolUtils {
/**
* 功能1:JSON验证和错误定位
*/
fun validateJSON(jsonString: String): Map<String, Any> {
val result = mutableMapOf<String, Any>()
val trimmed = jsonString.trim()
if (trimmed.isEmpty()) {
result["有效"] = false
result["错误"] = "JSON字符串为空"
return result
}
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) {
result["有效"] = false
result["错误"] = "JSON必须以{ 或 [ 开头"
return result
}
val stack = mutableListOf<Char>()
var inString = false
var escapeNext = false
var line = 1
var column = 1
for (i in trimmed.indices) {
val ch = trimmed[i]
if (ch == '\n') {
line++
column = 1
continue
}
column++
if (escapeNext) {
escapeNext = false
continue
}
if (ch == '\\' && inString) {
escapeNext = true
continue
}
if (ch == '"') {
inString = !inString
continue
}
if (!inString) {
when (ch) {
'{', '[' -> stack.add(ch)
'}' -> {
if (stack.isEmpty() || stack.last() != '{') {
result["有效"] = false
result["错误"] = "括号不匹配:多余的}"
result["位置"] = "行$line 列$column"
return result
}
stack.removeAt(stack.size - 1)
}
']' -> {
if (stack.isEmpty() || stack.last() != '[') {
result["有效"] = false
result["错误"] = "括号不匹配:多余的]"
result["位置"] = "行$line 列$column"
return result
}
stack.removeAt(stack.size - 1)
}
}
}
}
if (stack.isNotEmpty()) {
result["有效"] = false
result["错误"] = "括号不匹配:缺少闭合括号"
return result
}
if (inString) {
result["有效"] = false
result["错误"] = "字符串未闭合"
return result
}
result["有效"] = true
result["消息"] = "JSON有效"
return result
}
/**
* 功能2:JSON格式化
*/
fun formatJSON(jsonString: String, indentSize: Int = 2, sortKeys: Boolean = false): String {
val (isValid, _) = validateJSON(jsonString).let {
it["有效"] as Boolean to it["错误"]
}
if (!isValid) return "JSON无效,无法格式化"
val result = StringBuilder()
var indentLevel = 0
var inString = false
var escapeNext = false
val indent = " ".repeat(indentSize)
for (i in jsonString.indices) {
val ch = jsonString[i]
if (escapeNext) {
result.append(ch)
escapeNext = false
continue
}
if (ch == '\\' && inString) {
result.append(ch)
escapeNext = true
continue
}
if (ch == '"') {
result.append(ch)
inString = !inString
continue
}
if (!inString) {
when (ch) {
'{', '[' -> {
result.append(ch)
indentLevel++
result.append("\n").append(indent.repeat(indentLevel))
}
'}', ']' -> {
indentLevel--
result.append("\n").append(indent.repeat(indentLevel))
result.append(ch)
}
',' -> {
result.append(ch)
result.append("\n").append(indent.repeat(indentLevel))
}
':' -> {
result.append(ch).append(" ")
}
' ', '\n', '\r', '\t' -> {
// 跳过空白字符
}
else -> result.append(ch)
}
} else {
result.append(ch)
}
}
return result.toString()
}
/**
* 功能3:JSON压缩
*/
fun minifyJSON(jsonString: String): String {
val (isValid, _) = validateJSON(jsonString).let {
it["有效"] as Boolean to it["错误"]
}
if (!isValid) return "JSON无效,无法压缩"
val result = StringBuilder()
var inString = false
var escapeNext = false
for (i in jsonString.indices) {
val ch = jsonString[i]
if (escapeNext) {
result.append(ch)
escapeNext = false
continue
}
if (ch == '\\' && inString) {
result.append(ch)
escapeNext = true
continue
}
if (ch == '"') {
result.append(ch)
inString = !inString
continue
}
if (!inString) {
if (ch !in " \n\r\t") {
result.append(ch)
}
} else {
result.append(ch)
}
}
return result.toString()
}
/**
* 功能4:JSON转换为Map
*/
fun jsonToMap(jsonString: String): Map<String, Any>? {
return try {
val (isValid, _) = validateJSON(jsonString).let {
it["有效"] as Boolean to it["错误"]
}
if (!isValid) return null
val trimmed = jsonString.trim()
if (!trimmed.startsWith("{")) return null
val map = mutableMapOf<String, Any>()
var i = 1
while (i < trimmed.length - 1) {
while (i < trimmed.length && trimmed[i] in " \n\r\t") i++
if (trimmed[i] != '"') break
i++
val keyStart = i
while (i < trimmed.length && trimmed[i] != '"') i++
val key = trimmed.substring(keyStart, i)
i++
while (i < trimmed.length && trimmed[i] in " \n\r\t:") i++
val valueStart = i
var depth = 0
var inStr = false
while (i < trimmed.length) {
if (trimmed[i] == '"' && (i == 0 || trimmed[i-1] != '\\')) {
inStr = !inStr
}
if (!inStr) {
if (trimmed[i] in "{[") depth++
if (trimmed[i] in "}]") depth--
if ((trimmed[i] == ',' || trimmed[i] == '}') && depth == 0) break
}
i++
}
val value = trimmed.substring(valueStart, i).trim()
map[key] = value
if (i < trimmed.length && trimmed[i] == ',') i++
}
map
} catch (e: Exception) {
null
}
}
/**
* 功能5:JSON路径查询
*/
fun queryJSON(jsonString: String, path: String): String {
val (isValid, _) = validateJSON(jsonString).let {
it["有效"] as Boolean to it["错误"]
}
if (!isValid) return "JSON无效"
val parts = path.split(".")
var current = jsonString
for (part in parts) {
if (part.isEmpty()) continue
val pattern = "\"$part\"\\s*:\\s*([^,}\\]]+)".toRegex()
val match = pattern.find(current)
if (match != null) {
current = match.groupValues[1].trim()
} else {
return "路径不存在:$path"
}
}
return current
}
/**
* 获取JSON统计信息
*/
fun getJSONStats(jsonString: String): Map<String, Any> {
val stats = mutableMapOf<String, Any>()
val (isValid, _) = validateJSON(jsonString).let {
it["有效"] as Boolean to it["错误"]
}
stats["有效"] = isValid
stats["原始大小"] = jsonString.length
stats["压缩后大小"] = minifyJSON(jsonString).length
stats["压缩率"] = String.format("%.2f%%",
(1 - minifyJSON(jsonString).length.toDouble() / jsonString.length) * 100)
return stats
}
}
// 使用示例
fun main() {
println("KMP OpenHarmony JSON处理工具演示\n")
val jsonString = """
{
"name": "张三",
"age": 28,
"email": "zhangsan@example.com",
"address": {
"city": "北京",
"street": "中关村大街"
},
"hobbies": ["编程", "阅读", "运动"]
}
""".trimIndent()
println("原始JSON:")
println(jsonString)
println()
// 验证
val validation = JSONToolUtils.validateJSON(jsonString)
println("验证结果:${validation["消息"]}\n")
// 格式化
println("格式化后的JSON:")
println(JSONToolUtils.formatJSON(jsonString))
println()
// 压缩
println("压缩后的JSON:")
println(JSONToolUtils.minifyJSON(jsonString))
println()
// 统计信息
println("JSON统计信息:")
JSONToolUtils.getJSONStats(jsonString).forEach { (k, v) ->
println(" $k: $v")
}
}
Kotlin实现的详细说明
Kotlin实现提供了五个核心功能。JSON验证通过检查括号匹配和字符串完整性来验证JSON的有效性,并精确定位错误位置。JSON格式化通过添加缩进和换行使JSON更易读。JSON压缩移除所有不必要的空白字符以减少文件大小。JSON转换将JSON转换为Kotlin Map结构。JSON路径查询使用点号表示法查询嵌套的值。这个实现相比之前的版本更加完整,包含了错误定位、行列号追踪等高级功能。
JavaScript实现
完整的JavaScript代码实现
/**
* JSON处理和数据转换工具 - JavaScript版本
*/
class JSONToolJS {
/**
* 功能1:JSON验证和错误定位
*/
static validateJSON(jsonString) {
try {
const trimmed = jsonString.trim();
if (!trimmed) {
return { valid: false, message: "JSON字符串为空" };
}
if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
return { valid: false, message: "JSON必须以{ 或 [ 开头" };
}
const stack = [];
let inString = false;
let escapeNext = false;
let line = 1;
let column = 1;
for (let i = 0; i < trimmed.length; i++) {
const ch = trimmed[i];
if (ch === '\n') {
line++;
column = 1;
continue;
}
column++;
if (escapeNext) {
escapeNext = false;
continue;
}
if (ch === '\\' && inString) {
escapeNext = true;
continue;
}
if (ch === '"') {
inString = !inString;
continue;
}
if (!inString) {
if (ch === '{' || ch === '[') {
stack.push(ch);
} else if (ch === '}') {
if (stack.length === 0 || stack[stack.length - 1] !== '{') {
return {
valid: false,
message: "括号不匹配:多余的}",
position: `行${line} 列${column}`
};
}
stack.pop();
} else if (ch === ']') {
if (stack.length === 0 || stack[stack.length - 1] !== '[') {
return {
valid: false,
message: "括号不匹配:多余的]",
position: `行${line} 列${column}`
};
}
stack.pop();
}
}
}
if (stack.length > 0) {
return { valid: false, message: "括号不匹配:缺少闭合括号" };
}
if (inString) {
return { valid: false, message: "字符串未闭合" };
}
JSON.parse(trimmed);
return { valid: true, message: "JSON有效" };
} catch (e) {
return { valid: false, message: `验证错误:${e.message}` };
}
}
/**
* 功能2:JSON格式化
*/
static formatJSON(jsonString, indentSize = 2) {
const { valid } = this.validateJSON(jsonString);
if (!valid) return "JSON无效,无法格式化";
try {
const parsed = JSON.parse(jsonString);
return JSON.stringify(parsed, null, indentSize);
} catch (e) {
return "格式化失败";
}
}
/**
* 功能3:JSON压缩
*/
static minifyJSON(jsonString) {
const { valid } = this.validateJSON(jsonString);
if (!valid) return "JSON无效,无法压缩";
try {
const parsed = JSON.parse(jsonString);
return JSON.stringify(parsed);
} catch (e) {
return "压缩失败";
}
}
/**
* 功能4:JSON转换为对象
*/
static jsonToObject(jsonString) {
try {
const { valid } = this.validateJSON(jsonString);
if (!valid) return null;
return JSON.parse(jsonString);
} catch (e) {
return null;
}
}
/**
* 功能5:JSON路径查询
*/
static queryJSON(jsonString, path) {
try {
const { valid } = this.validateJSON(jsonString);
if (!valid) return "JSON无效";
const obj = JSON.parse(jsonString);
const parts = path.split('.');
let current = obj;
for (const part of parts) {
if (current && typeof current === 'object') {
current = current[part];
} else {
return "路径不存在:" + path;
}
}
return JSON.stringify(current);
} catch (e) {
return "查询失败";
}
}
/**
* 获取JSON统计信息
*/
static getJSONStats(jsonString) {
const { valid } = this.validateJSON(jsonString);
const minified = this.minifyJSON(jsonString);
return {
有效: valid,
原始大小: jsonString.length,
压缩后大小: minified.length,
压缩率: ((1 - minified.length / jsonString.length) * 100).toFixed(2) + '%'
};
}
}
// 导出供Node.js使用
if (typeof module !== 'undefined' && module.exports) {
module.exports = JSONToolJS;
}
JavaScript实现的详细说明
JavaScript版本充分利用了JavaScript内置的JSON对象。验证功能使用try-catch和JSON.parse来检查有效性,并追踪行列号。格式化和压缩功能使用JSON.stringify的第三个参数来控制输出格式。路径查询使用对象属性访问来遍历嵌套结构。这个实现比之前的版本更加完整,包含了错误位置追踪等高级功能。
ArkTS调用实现
完整的ArkTS代码实现
/**
* JSON处理和数据转换工具 - ArkTS版本(OpenHarmony鸿蒙)
*/
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct JSONToolPage {
@State jsonInput: string = '{"name":"张三","age":28,"city":"北京"}';
@State result: string = '';
@State selectedTool: string = '验证';
@State isLoading: boolean = false;
@State allResults: string = '';
webviewController: webview.WebviewController = new webview.WebviewController();
validateJSON(jsonString: string): { valid: boolean; message: string } {
try {
const trimmed = jsonString.trim();
if (!trimmed) {
return { valid: false, message: "JSON字符串为空" };
}
if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {
return { valid: false, message: "JSON必须以{ 或 [ 开头" };
}
const stack: string[] = [];
let inString = false;
let escapeNext = false;
for (let i = 0; i < trimmed.length; i++) {
const ch = trimmed[i];
if (escapeNext) {
escapeNext = false;
continue;
}
if (ch === '\\' && inString) {
escapeNext = true;
continue;
}
if (ch === '"') {
inString = !inString;
continue;
}
if (!inString) {
if (ch === '{' || ch === '[') {
stack.push(ch);
} else if (ch === '}') {
if (stack.length === 0 || stack[stack.length - 1] !== '{') {
return { valid: false, message: "括号不匹配" };
}
stack.pop();
} else if (ch === ']') {
if (stack.length === 0 || stack[stack.length - 1] !== '[') {
return { valid: false, message: "括号不匹配" };
}
stack.pop();
}
}
}
if (stack.length > 0) {
return { valid: false, message: "缺少闭合括号" };
}
JSON.parse(trimmed);
return { valid: true, message: "JSON有效" };
} catch (e) {
return { valid: false, message: `错误:${e}` };
}
}
formatJSON(jsonString: string, indentSize: number = 2): string {
const { valid } = this.validateJSON(jsonString);
if (!valid) return "JSON无效";
try {
const parsed = JSON.parse(jsonString);
return JSON.stringify(parsed, null, indentSize);
} catch (e) {
return "格式化失败";
}
}
minifyJSON(jsonString: string): string {
const { valid } = this.validateJSON(jsonString);
if (!valid) return "JSON无效";
try {
const parsed = JSON.parse(jsonString);
return JSON.stringify(parsed);
} catch (e) {
return "压缩失败";
}
}
jsonToObject(jsonString: string): string {
try {
const { valid } = this.validateJSON(jsonString);
if (!valid) return "JSON无效";
const obj = JSON.parse(jsonString);
return JSON.stringify(obj, null, 2);
} catch (e) {
return "转换失败";
}
}
queryJSON(jsonString: string, path: string): string {
try {
const { valid } = this.validateJSON(jsonString);
if (!valid) return "JSON无效";
const obj = JSON.parse(jsonString);
const parts = path.split('.');
let current = obj;
for (const part of parts) {
if (current && typeof current === 'object') {
current = current[part];
} else {
return "路径不存在";
}
}
return JSON.stringify(current);
} catch (e) {
return "查询失败";
}
}
getJSONStats(jsonString: string): string {
const { valid } = this.validateJSON(jsonString);
const minified = this.minifyJSON(jsonString);
const stats = {
有效: valid,
原始大小: jsonString.length,
压缩后大小: minified.length,
压缩率: ((1 - minified.length / jsonString.length) * 100).toFixed(2) + '%'
};
return JSON.stringify(stats, null, 2);
}
async executeJSONTool() {
this.isLoading = true;
try {
let result = '';
switch (this.selectedTool) {
case '验证':
const validation = this.validateJSON(this.jsonInput);
result = `${validation.message}`;
break;
case '格式化':
result = this.formatJSON(this.jsonInput);
break;
case '压缩':
result = this.minifyJSON(this.jsonInput);
break;
case '转换':
result = this.jsonToObject(this.jsonInput);
break;
case '统计':
result = this.getJSONStats(this.jsonInput);
break;
}
this.result = result;
const results = [];
const validation = this.validateJSON(this.jsonInput);
results.push(`验证: ${validation.message}`);
results.push(`格式化:\n${this.formatJSON(this.jsonInput)}`);
results.push(`压缩: ${this.minifyJSON(this.jsonInput)}`);
results.push(`统计:\n${this.getJSONStats(this.jsonInput)}`);
this.allResults = `所有工具结果:\n${results.join('\n\n')}`;
} catch (error) {
this.result = '执行错误:' + error;
}
this.isLoading = false;
}
build() {
Column() {
Row() {
Text('JSON处理和数据转换工具')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.fontColor(Color.White)
}
.width('100%')
.height(60)
.backgroundColor('#1565C0')
.justifyContent(FlexAlign.Center)
Scroll() {
Column({ space: 16 }) {
Column() {
Text('输入JSON:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
TextInput({ placeholder: '请输入JSON' })
.value(this.jsonInput)
.onChange((value: string) => {
this.jsonInput = value;
})
.width('100%')
.height(100)
.padding(8)
.backgroundColor(Color.White)
.borderRadius(4)
}
.width('100%')
.padding(12)
.backgroundColor('#E3F2FD')
.borderRadius(8)
Column() {
Text('选择工具:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
Select([
{ value: '验证' },
{ value: '格式化' },
{ value: '压缩' },
{ value: '转换' },
{ value: '统计' }
])
.value(this.selectedTool)
.onSelect((index: number, value: string) => {
this.selectedTool = value;
})
.width('100%')
}
.width('100%')
.padding(12)
.backgroundColor('#E3F2FD')
.borderRadius(8)
if (this.result) {
Column() {
Text('结果:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
Text(this.result)
.fontSize(12)
.width('100%')
.padding(8)
.backgroundColor('#F5F5F5')
.borderRadius(4)
}
.width('100%')
.padding(12)
.backgroundColor('#F5F5F5')
.borderRadius(8)
}
if (this.allResults) {
Column() {
Text('所有结果:')
.fontSize(14)
.fontWeight(FontWeight.Bold)
.width('100%')
Text(this.allResults)
.fontSize(12)
.width('100%')
.padding(8)
.backgroundColor('#E8F5E9')
.borderRadius(4)
}
.width('100%')
.padding(12)
.backgroundColor('#E8F5E9')
.borderRadius(8)
}
Button('执行工具')
.width('100%')
.onClick(() => this.executeJSONTool())
.enabled(!this.isLoading)
if (this.isLoading) {
LoadingProgress()
.width(40)
.height(40)
}
}
.width('100%')
.padding(16)
}
.layoutWeight(1)
}
.width('100%')
.height('100%')
.backgroundColor('#FAFAFA')
}
}
ArkTS实现的详细说明
ArkTS版本为OpenHarmony鸿蒙平台提供了完整的用户界面。通过@State装饰器,我们可以管理应用的状态。这个实现包含了JSON输入框、工具选择和结果显示功能。用户可以输入JSON,选择不同的工具,查看处理结果。相比之前的版本,这个实现增加了更多的错误处理和用户反馈机制。
应用场景分析
1. API开发和测试
在API开发中,需要验证请求和响应的JSON格式。开发者使用JSON工具来调试API并确保数据格式正确。
2. 数据处理和转换
在数据处理中,需要对JSON进行格式化和美化。数据处理系统使用JSON工具来处理和转换数据。
3. 配置管理
在配置管理中,需要验证配置文件的有效性。配置系统使用JSON工具来验证和处理配置。
4. 日志分析
在日志分析中,需要解析和格式化JSON日志。日志分析工具使用JSON工具来处理日志。
5. 数据迁移和集成
在数据迁移中,需要转换和验证JSON数据。迁移工具使用JSON工具来处理数据。
性能优化建议
1. 使用流式处理
对于大型JSON文件,使用流式处理可以减少内存占用。
2. 缓存验证结果
对于频繁验证的JSON,可以缓存验证结果。
3. 并行处理
对于多个JSON文件,可以并行处理以提高效率。
4. 优化查询算法
使用索引和缓存来优化JSON路径查询。
总结
JSON处理和数据转换工具是现代应用开发中不可或缺的工具。通过在KMP框架下实现这套工具,我们可以在多个平台上使用同一套代码,提高开发效率。这个工具提供了验证、格式化、压缩、转换和查询等多种功能,可以满足大多数JSON处理需求。
在OpenHarmony鸿蒙平台上,我们可以通过ArkTS调用这些工具,为用户提供完整的JSON处理体验。掌握这套工具,不仅能够帮助开发者高效处理JSON数据,更重要的是能够在实际项目中灵活应用,解决数据验证、格式转换等实际问题。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐
所有评论(0)