鸿蒙开发——使用ArkTs处理XML文本

news2024/12/26 14:50:25

1、概 述

XML(可扩展标记语言)是一种用于描述数据的标记语言,旨在提供一种通用的方式来传输和存储数据,特别是Web应用程序中经常使用的数据。XML并不预定义标记。因此,XML更加灵活,并且可以适用于广泛的应用领域。

XML文档由元素(element)、属性(attribute)和内容(content)组成。

    • 内容则是元素包含的数据或子元素。

    • 属性提供了有关元素的其他信息。

    • 元素指的是标记对,包含文本、属性或其他元素。

XML还可以通过使用XML Schema或DTD(文档类型定义)来定义文档结构。这些机制允许开发人员创建自定义规则以验证XML文档是否符合其预期的格式。

XML还支持命名空间、实体引用、注释、处理指令等特性,使其能够灵活地适应各种数据需求。

语言基础类库提供了XML相关的基础能力,包括:XML的生成、XML的解析和XML的转换。

2、生成XML

一个生成XML的示例如下(关注 9 ~ 41行,genXml方法):

import { xml, util } from '@kit.ArkTS';@Entry@Component@Previewstruct Index {  @State result: string = '';  genXml() {    // 方式1:基于Arraybuffer构造XmlSerializer对象    let arrayBuffer: ArrayBuffer = new ArrayBuffer(2048); // 创建一个2048字节的缓冲区    let thatSer: xml.XmlSerializer = new xml.XmlSerializer(arrayBuffer); // 基于Arraybuffer构造XmlSerializer对象    // 方式2:基于DataView构造XmlSerializer对象    // let arrayBuffer: ArrayBuffer = new ArrayBuffer(2048);    // let dataView: DataView = new DataView(arrayBuffer);    // let thatSer: xml.XmlSerializer = new xml.XmlSerializer(dataView);    thatSer.setDeclaration(); // 写入xml的声明    thatSer.startElement('bookstore'); // 写入元素开始标记    thatSer.startElement('book'); // 嵌套元素开始标记    thatSer.setAttributes('category', 'COOKING'); // 写入属性及属性值    thatSer.startElement('title');    thatSer.setAttributes('lang', 'en');    thatSer.setText('Everyday'); // 写入标签值    thatSer.endElement(); // 写入结束标记    thatSer.startElement('author');    thatSer.setText('Giana');    thatSer.endElement();    thatSer.startElement('year');    thatSer.setText('2005');    thatSer.endElement();    thatSer.endElement();    thatSer.endElement();    let view: Uint8Array = new Uint8Array(arrayBuffer); // 使用Uint8Array读取arrayBuffer的数据    let textDecoder: util.TextDecoder = util.TextDecoder.create(); // 调用util模块的TextDecoder类    let res: string = textDecoder.decodeToString(view); // 对view解码    // res输出结果    this.result = res;  }  build() {    Column() {      Row() {        Button('生成XML')          .onClick(() => {            this.genXml();          })          .width('100%')      }      .width('100%')      Row() {        Text(this.result)          .width('100%')          .padding(10)          .borderColor(Color.Gray)          .borderWidth(1)      }.width('100%')    }    .height('100%')  }}

效果如下:

图片

3、解析XML

对于XML的解析,一般包括

  1. 解析XML标签和标签值;

  2. 解析XML属性和属性值

  3. 解析XML事件类型和元素深度。

XML模块提供XmlPullParser类对XML文件解析,输入为含有XML文本的ArrayBuffer或DataView,输出为解析得到的信息。

下面分别针对这三种情况做示例讨论。

👉🏻 解析标签与标签内的值

一个解析XML标签和标签值的Demo如下(关注 9 ~ 36行,parseXML方法):​​​​​​​

import { xml, util } from '@kit.ArkTS';@Entry@Component@Previewstruct Index {  @State result: string = '';  parseXml() {  // xml案例    let strXml: string =      '<?xml version="1.0" encoding="utf-8"?>' +        '<note importance="high" logged="true">' +        '<title>Play</title>' +        '<lens>Work</lens>' +        '</note>';    let textEncoder: util.TextEncoder = new util.TextEncoder();    let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); // 对数据编码,防止包含中文字符乱码    // 方式1:基于ArrayBuffer构造XmlPullParser对象    let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8');    // 方式2:基于DataView构造XmlPullParser对象    // let dataView: DataView = new DataView(arrBuffer.buffer as object as ArrayBuffer);    // let that: xml.XmlPullParser = new xml.XmlPullParser(dataView, 'UTF-8');    let str: string = '';    // 自定义回调函数,本例直接打印出标签及标签值。    const  func = (name: string, value: string): boolean => {      str = name + value + '\n';      this.result += str;      return true; //true:继续解析 false:停止解析    }    let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, tagValueCallbackFunction:func};    that.parse(options);  }  build() {    Column() {      Row() {        Button('解析XML')          .onClick(() => {            this.parseXml();          })          .width('100%')      }      .width('100%')      Row() {        Text(this.result)          .width('100%')          .padding(10)          .borderColor(Color.Gray)          .borderWidth(1)      }.width('100%')    }    .height('100%')  }}

效果如下:

图片

👉🏻 解析XML属性与属性值

一个解析XML属性和属性值的Demo如下(关注 9 ~ 30行,parseXML方法):​​​​​​​

import { xml, util } from '@kit.ArkTS';@Entry@Component@Previewstruct Index {  @State result: string = '';  parseXml() {    let strXml: string =      '<?xml version="1.0" encoding="utf-8"?>' +        '<note importance="high" logged="true">' +        '    <title>Play</title>' +        '    <title>Happy</title>' +        '    <lens>Work</lens>' +        '</note>';    let textEncoder: util.TextEncoder = new util.TextEncoder();    let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); // 对数据编码,防止包含中文字符乱码    let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8');    let str: string = '';    const func = (name: string, value: string): boolean => {      str += name + ' ' + value + ' \n';      return true; // true:继续解析 false:停止解析    }    let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, attributeValueCallbackFunction:func};    that.parse(options);    this.result = str; // 一次打印出所有的属性及其值  }  build() {    Column() {      Row() {        Button('解析XML')          .onClick(() => {            this.parseXml();          })          .width('100%')      }      .width('100%')      Row() {        Text(this.result)          .width('100%')          .padding(10)          .borderColor(Color.Gray)          .borderWidth(1)      }.width('100%')    }    .height('100%')  }}

效果如下:

图片

👉🏻 解析XML事件类型和元素深度

一个解析XML事件类型和元素深度的Demo如下(关注 9 ~ 30行,parseXML方法):​​​​​​​

import { xml, util } from '@kit.ArkTS';@Entry@Component@Previewstruct Index {  @State result: string = '';  parseXml() {    let strXml: string =      '<?xml version="1.0" encoding="utf-8"?>' +        '<note importance="high" logged="true">' +        '<title>Play</title>' +        '</note>';    let textEncoder: util.TextEncoder = new util.TextEncoder();    let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); // 对数据编码,防止包含中文字符乱码    let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8');    let str: string  = '';    const func = (name: xml.EventType, value: xml.ParseInfo): boolean => {      str = name + ' ' + value.getDepth() + '\n'; // getDepth 获取元素的当前深度      this.result += str;      return true; //true:继续解析 false:停止解析    }    let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, tokenValueCallbackFunction:func};    that.parse(options);  }  build() {    Column() {      Row() {        Button('解析XML')          .onClick(() => {            this.parseXml();          })          .width('100%')      }      .width('100%')      Row() {        Text(this.result)          .width('100%')          .padding(10)          .borderColor(Color.Gray)          .borderWidth(1)      }.width('100%')    }    .height('100%')  }}

效果如下:

图片

其中对输出结果解释如下:​​​​​​​

 0 0 // 0:<?xml version="1.0" encoding="utf-8"?> 对应事件类型        START_DOCUMENT值为0  0:起始深度为0 2 1 // 2:<note importance="high" logged="true"> 对应事件类型START_TAG值为2       1:深度为1 2 2 // 2:<title>对应事件类型START_TAG值为2                                       2:深度为2 4 2 // 4:Play对应事件类型TEXT值为4                                               2:深度为2 3 2 // 3:</title>对应事件类型END_TAG值为3                                        2:深度为2 3 1 // 3:</note>对应事件类型END_TAG值为3                                         1:深度为1(与<note对应>) 1 0 // 1:对应事件类型END_DOCUMENT值为1                                           0:深度为0

【 解析选项参数 】

通过上面三个例子,我们可以观察到,核心都涉及到xml.ParseOptions选项参数。通过这个参数,我们可以设置对应的回调函数和一些解析行为。ParseOptions参数总结如下:

名称类型说明
supportDoctypeboolean是否解析文档类型,默认false,表示不解析。
ignoreNameSpaceboolean是否忽略命名空间,默认false,表示不忽略。
tagValueCallbackFunction(name: string, value: string) => boolean解析开始标签、标签值和结束标签,默认undefined,表示不解析。
attributeValueCallbackFunction(name: string, value: string) => boolean解析属性和属性值,默认undefined,表示不解析。
tokenValueCallbackFunction(eventType: EventType, value: ParseInfo) => boolean解析元素事件类型(EventType)和ParseInfo属性,默认undefined,表示不解析。

其中EventType是事件类型枚举,定义如下:

名称说明
START_DOCUMENT0启动文件事件。
END_DOCUMENT1结束文件事件。
START_TAG2启动标签事件。
END_TAG3结束标签事件。
TEXT4文本事件。
CDSECT5CDATA事件。
COMMENT6XML注释事件。
DOCDECL7XML文档类型声明事件。
INSTRUCTION8XML处理指令声明事件。
ENTITY_REFERENCE9实体引用事件。
WHITESPACE10空白事件。

4、转换XML为JSON对象

将XML文本转换为JSON对象可以更轻松地处理和操作数据,并且更适合在JS应用程序中使用。

语言基础类库提供ConvertXML类将XML文本转换为JSON对象,输入为待转换的XML字符串及转换选项,输出为转换后的JSON对象。

一个转换示例如下:​​​​​​​

import { convertxml } from '@kit.ArkTS';@Entry@Component@Previewstruct Index {  @State result: string = '';  convertXML() {    let xml: string =      '<?xml version="1.0" encoding="utf-8"?>' +        '<note importance="high" logged="true">' +        '    <title>Happy</title>' +        '    <todo>Work</todo>' +        '    <todo>Play</todo>' +        '</note>';    let options: convertxml.ConvertOptions = {      // trim: false 转换后是否删除文本前后的空格,否      // declarationKey: "_declaration" 转换后文件声明使用_declaration来标识      // instructionKey: "_instruction" 转换后指令使用_instruction标识      // attributesKey: "_attributes" 转换后属性使用_attributes标识      // textKey: "_text" 转换后标签值使用_text标识      // cdataKey: "_cdata" 转换后未解析数据使用_cdata标识      // docTypeKey: "_doctype" 转换后文档类型使用_doctype标识      // commentKey: "_comment" 转换后注释使用_comment标识      // parentKey: "_parent" 转换后父类使用_parent标识      // typeKey: "_type" 转换后元素类型使用_type标识      // nameKey: "_name" 转换后标签名称使用_name标识      // elementsKey: "_elements" 转换后元素使用_elements标识      trim: false,      declarationKey: "_declaration",      instructionKey: "_instruction",      attributesKey: "_attributes",      textKey: "_text",      cdataKey: "_cdata",      doctypeKey: "_doctype",      commentKey: "_comment",      parentKey: "_parent",      typeKey: "_type",      nameKey: "_name",      elementsKey: "_elements"    }    let conv: convertxml.ConvertXML = new convertxml.ConvertXML();    let result: object = conv.convertToJSObject(xml, options);    let strRes: string = JSON.stringify(result); // 将js对象转换为json字符串,用于显式输出    console.info(strRes);    this.result = strRes;  }  build() {    Column() {      Row() {        Button('解析XML')          .onClick(() => {            this.convertXML();          })          .width('100%')      }      .width('100%')      Row() {        Text(this.result)          .width('100%')          .padding(10)          .borderColor(Color.Gray)          .borderWidth(1)      }.width('100%')    }    .height('100%')  }}

效果如下:

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2254229.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序介绍-以及写项目流程(重要)

前言&#xff1a;本篇文章介绍微信小程序以及项目介绍&#xff1a; 文章介绍&#xff1a;介绍了微信小程序常用的指令、组件、api。tips&#xff1a;最好按照官方文档来进行学习&#xff0c;大致可以我的目录来学习&#xff0c;对于写项目是没有问题的 微信小程序官方文档https…

嵌入式蓝桥杯学习5 定时中断实现按键

Cubemx配置 打开cubemx。 前面的配置与前文一样&#xff0c;这里主要配置基本定时器的定时功能。 1.在Timer中点击TIM6&#xff0c;勾选activated。配置Parameter Settings中的预分频器&#xff08;PSC&#xff09;和计数器&#xff08;auto-reload Register&#xff09; 补…

特别分享!SIM卡接口功能及其电路设计相关注意事项

SIM卡接口功能及其电路设计相关注意事项对电子工程师来说非常重要。SIM卡接口用于连接SIM卡并读取SIM卡信息&#xff0c;以便在注册4G网络时进行鉴权身份验证&#xff0c;是4G通信系统的必要功能。 一、SIM卡接口功能描述 Air700ECQ/Air700EAQ/Air700EMQ系列模组支持1路USIM接…

OpenGL ES详解——文字渲染

目录 一、文字渲染 二、经典文字渲染&#xff1a;位图字体 1.概念 2.优缺点 三、现代文字渲染&#xff1a;FreeType 1.着色器 2.渲染一行文字 四、关于未来 一、文字渲染 当你在图形计算领域冒险到了一定阶段以后你可能会想使用OpenGL来绘制文字。然而&#xff0c;可能…

devops-Dockerfile+Jenkinsfile方式部署Java前后端应用

文章目录 概述部署前端Vue应用一、环境准备1、Dockerfile2、.dockerignore3、nginx.conf4、Jenkinsfile 二、Jenkins部署1、新建任务2、流水线3、Build Now 构建 & 访问 Springboot后端应用1. 准备工作2. 创建项目结构3. 编写 Dockerfile后端 Dockerfile (backend/Dockerfi…

VTK编程指南<三>:基于VTK入门程序解析来理解VTK基础知识

1、VTK入门程序 下面是一个完整的Vtk入门程序&#xff0c;我们基于这个程序来对VTK的基本知识进行一个初步了解。 #include <iostream>#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2 VTK_MODULE_INI…

十二、消息队列-MQ

文章目录 前言一、MQ介绍1. 背景2. 解决思路3. 解决方案 二、应用场景三、常见的MQ产品四、MQ选型总结五、相关知识1. AMQP2. JMS 五、如何设计实现一个消息队列1. 设计消息队列的思路2. 实现队列基本功能1. RPC通信协议2. 高可用3. 服务端承载消息堆积的能力4. 存储子系统的选…

新手如何做好一份技术文档

对于新手来说&#xff0c;编写技术文档可能是一项挑战&#xff0c;但这也是一个提升自己技术写作能力的绝佳机会。技术文档不仅仅是代码的补充说明&#xff0c;它更是团队协作和项目成功的基石。本文将为你提供一些实用的指导和建议&#xff0c;帮助你编写出一份高质量的技术文…

如何设置PPT以“只读方式”打开?3种简单方法!

在PPT中设置文件为“只读”模式&#xff0c;可以防止自己意外修改&#xff0c;也可以防止他人对文件内容进行修改&#xff0c;确保文件的安全性。根据需求不同&#xff0c;PPT可以设置3种不同的”只读方式“&#xff0c;一起来看看吧&#xff01; 方式1&#xff1a;设置文件为只…

DICOM医学影象应用篇——多平面重建(MPR)在DICOM医学影像中的应用详解

目录 MPR(多平面重建)概述 基本原理 具体实现 代码详解 总结 MPR(多平面重建)概述 多平面重建&#xff08;MPR, Multi-Planar Reconstruction&#xff09;是一项用于从三维医学影像数据集中生成不同平面的二维切片的技术。通常应用于CT或MRI数据集&#xff0c;MPR可以帮助医…

Vue前端开发-多级路由配置

在Vue 路由数组中&#xff0c;允许配置多级的路由对象结构&#xff0c;可以是二级、三级或者更多级别&#xff0c;最大级别原则上没有限制&#xff0c;但通常最大的是三或四级&#xff0c;这种路由结构&#xff0c;称之为多级路由。 例如&#xff1a;一级路由地址/list&#x…

【二分查找】力扣 875. 爱吃香蕉的珂珂

一、题目 二、思路 速度 k&#xff08;单位&#xff1a;根/小时&#xff09;是存在一个取值范围的。 速度越大肯定在规定的时间之内一定会吃完全部的香蕉&#xff0c;但也是可以确定出一个上界的。由于只要保证一小时之内&#xff0c;可以吃完香蕉数目最多的那一堆的香蕉&…

C语言——指针基础

1 指针基础 怎么获得变量地址 1 如何产生一个指针变量——>类型* 标识符;int* p1;char* p2;double* p3;//不同类型的基本指针占用内存是一样的都是4个字节&#xff08;32位&#xff09;/8个字节&#xff08;64位&#xff09;&#xff0c;都是存的地址2 数组名是数组首地址…

Leetcode day1.两数相加(2) 2.整数反转(7)

注意点&#xff1a;1.链表会出现其中一个已经为空&#xff0c;另一个缺还是有数据 2.相加时会出现进位操作 解法一、 利用队列的性质&#xff08;基础不好 第一时间想到的&#xff09; 很像队列的性质&#xff0c;先进先出&#xff0c;逐步计算。但是最后要换成链表样式。 …

在Ubuntu-22.04 [WSL2]中配置Docker

文章目录 0. 进入Ubuntu-22.041. 更新系统软件包2. 安装Docker相关依赖包3. 添加Docker官方GPG密钥4. 添加Docker软件源5. 安装Docker Engine5.1 更新软件包列表5.2 安装Docker相关软件包 6. 验证Docker安装是否成功6.1 查看Docker版本信息6.2 启动Docker6.3 配置镜像加速器6.4…

51单片机应用开发(进阶)---串口接收字符命令

实现目标 1、巩固UART知识&#xff1b; 2、掌握串口接收字符数据&#xff1b; 3、具体实现目标&#xff1a;&#xff08;1&#xff09;上位机串口助手发送多字符命令&#xff0c;单片机接收命令作相应的处理&#xff08;如&#xff1a;openled1 即打开LED1;closeled1 即关…

【查询基础】.NET开源 ORM 框架 SqlSugar 系列

&#x1f4a5; .NET开源 ORM 框架 SqlSugar 系列 &#x1f389;&#x1f389;&#x1f389; 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列…

基于Matlab BP神经网络的电力负荷预测模型研究与实现

随着电力系统的复杂性和规模的不断增长&#xff0c;准确的电力负荷预测对于电网的稳定性和运行效率至关重要。传统的负荷预测方法依赖于历史数据和简单的统计模型&#xff0c;但这些方法在处理非线性和动态变化的负荷数据时&#xff0c;表现出较大的局限性。近年来&#xff0c;…

LeetCode - #150 逆波兰表达式求值

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

mysql基础学习1

useradd -r -g mysql -s /bin/false mysql (-r)系统用户 不能登录 A temporary password is generated for rootlocalhost: d>#jT7rfoaz) 看是否启动 看进程 端口 直接连接 看日志 varchar (20) char(20)更耗空间 create table student_info(id int,name varchar(20),s…