首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

HarmonyOS Next开发学习手册——XML生成、解析与转换

  • 25-02-22 06:41
  • 2213
  • 8947
blog.csdn.net

概述

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

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

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

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

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

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

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

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

XML生成

XML可以作为数据交换格式,被各种系统和应用程序所支持。例如Web服务,可以将结构化数据以XML格式进行传递。

XML还可以作为消息传递格式,在分布式系统中用于不同节点之间的通信与交互。

注意事项

  • XML标签必须成对出现,生成开始标签就要生成结束标签。

  • XML标签对大小写敏感,开始标签与结束标签大小写要一致。

开发步骤

XML模块提供XmlSerializer类来生成XML文件,输入为固定长度的Arraybuffer或DataView对象,该对象用于存放输出的XML数据。

通过调用不同的方法来写入不同的内容,如startElement(name: string)写入元素开始标记,setText(text: string)写入标签值。

XML模块的API接口可以参考 @ohos.xml 的详细描述,按需求调用对应函数可以生成一份完整的XML文件。

  1. 引入模块。
import { xml, util } from '@kit.ArkTS';
  • 1
  1. 创建缓冲区,构造XmlSerializer对象(可以基于Arraybuffer构造XmlSerializer对象, 也可以基于DataView构造XmlSerializer对象)。
// 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); // 创建一个2048字节的缓冲区
let dataView: DataView = new DataView(arrayBuffer); // 使用DataView对象操作ArrayBuffer对象
let thatSer: xml.XmlSerializer = new xml.XmlSerializer(dataView); // 基于DataView构造XmlSerializer对象
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. 调用XML元素生成函数。
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('Giada');
thatSer.endElement();
thatSer.startElement('year');
thatSer.setText('2005');
thatSer.endElement();
thatSer.endElement();
thatSer.endElement();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  1. 使用Uint8Array操作Arraybuffer,调用TextDecoder对Uint8Array解码后输出。
let view: Uint8Array = new Uint8Array(arrayBuffer); // 使用Uint8Array读取arrayBuffer的数据
let textDecoder: util.TextDecoder = util.TextDecoder.create(); // 调用util模块的TextDecoder类
let res: string = textDecoder.decodeWithStream(view); // 对view解码
console.info(res);
  • 1
  • 2
  • 3
  • 4

输出结果如下:

\r\n  \r\n    Everyday\r\n    Giada\r\n    2005\r\n  \r\n
  • 1

XML解析

对于以XML作为载体传递的数据,实际使用中需要对相关的节点进行解析,一般包括 解析XML标签和标签值 、 解析XML属性和属性值 、 解析XML事件类型和元素深度 三类场景。

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

表1 XML解析选项

名称类型必填说明
supportDoctypeboolean否是否忽略文档类型。默认为false,表示对文档类型进行解析。
ignoreNameSpaceboolean否是否忽略命名空间。默认为false,表示对命名空间进行解析。
tagValueCallbackFunction(name: string, value: string) => boolean否获取tagValue回调函数,打印标签及标签值。默认为null,表示不进行XML标签和标签值的解析。
attributeValueCallbackFunction(name: string, value: string) => boolean否获取attributeValue回调函数, 打印属性及属性值。默认为null,表示不进行XML属性和属性值的解析。
tokenValueCallbackFunction(eventType: EventType, value: ParseInfo) => boolean否获取tokenValue回调函数,打印标签事件类型及parseInfo对应属性。默认为null,表示不进行XML事件类型解析。

注意事项

  • XML解析及转换需要确保传入的XML数据符合标准格式。

  • XML解析目前不支持按指定节点解析对应的节点值。

解析XML标签和标签值

  1. 引入模块。
import { xml, util } from '@kit.ArkTS'; // 需要使用util模块函数对文件编码
  • 1
  1. 对XML文件编码后调用XmlPullParser。

可以基于ArrayBuffer构造XmlPullParser对象, 也可以基于DataView构造XmlPullParser对象。

let strXml: string =
'' +
  '' +
  'Play' +
  'Work' +
  '';
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');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. 自定义回调函数,本例直接打印出标签及标签值。
let str: string = '';
function func(name: string, value: string): boolean {
  str = name + value;
  console.info(str);
  return true; //true:继续解析 false:停止解析
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 设置解析选项,调用parse函数。
let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, tagValueCallbackFunction:func};
that.parse(options);
  • 1
  • 2

输出结果如下所示:

note
title
Play
title
lens
Work
lens
note
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

解析XML属性和属性值

  1. 引入模块。
import { xml, util } from '@kit.ArkTS'; // 需要使用util模块函数对文件编码
  • 1
  1. 对XML文件编码后调用XmlPullParser。
let strXml: string =
  '' +
    '' +
    '    Play' +
    '    Happy' +
    '    Work' +
    '';
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');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  1. 自定义回调函数,本例直接打印出属性及属性值。
let str: string = '';
function func(name: string, value: string): boolean {
  str += name + ' ' + value + ' ';
  return true; // true:继续解析 false:停止解析
}
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 设置解析选项,调用parse函数。
let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, tokenValueCallbackFunction:func};
that.parse(options);
  • 1
  • 2

输出结果如下所示:

let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, attributeValueCallbackFunction:func};
that.parse(options);
console.info(str); // 一次打印出所有的属性及其值
  • 1
  • 2
  • 3

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

  1. 引入模块。
import { xml, util } from '@kit.ArkTS'; // 需要使用util模块函数对文件编码
  • 1
  1. 对XML文件编码后调用XmlPullParser。
let strXml: string =
  '' +
  '' +
  'Play' +
  '';
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');
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. 自定义回调函数,本例直接打印元素事件类型及元素深度。
let str: string  = '';
function func(name: xml.EventType, value: xml.ParseInfo): boolean {
  str = name + ' ' + value.getDepth(); // getDepth 获取元素的当前深度
  console.info(str)
  return true; //true:继续解析 false:停止解析
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 设置解析选项,调用parse函数。
let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, tokenValueCallbackFunction:func};
that.parse(options);
  • 1
  • 2

输出结果如下所示:

 0 0 // 0: 对应事件类型        START_DOCUMENT值为0  0:起始深度为0
 2 1 // 2: 对应事件类型START_TAG值为2       1:深度为1
 2 2 // 2:对应事件类型START_TAG值为2                                       2:深度为2
 4 2 // 4:Play对应事件类型TEXT值为4                                               2:深度为2
 3 2 // 3:对应事件类型END_TAG值为3                                        2:深度为2
 3 1 // 3:对应事件类型END_TAG值为3                                         1:深度为1(与)
 1 0 // 1:对应事件类型END_DOCUMENT值为1                                           0:深度为0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

场景示例

此处以调用所有解析选项为例,提供解析XML标签、属性和事件类型的开发示例。

import { xml, util } from '@kit.ArkTS';

let strXml: string =
  '' +
    '' +
    'Everyday' +
    'Giada' +
    '';
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 = '';

function tagFunc(name: string, value: string): boolean {
  str = name + value;
  console.info('tag-' + str);
  return true;
}

function attFunc(name: string, value: string): boolean {
  str = name + ' ' + value;
  console.info('attri-' + str);
  return true;
}

function tokenFunc(name: xml.EventType, value: xml.ParseInfo): boolean {
  str = name + ' ' + value.getDepth();
  console.info('token-' + str);
  return true;
}

let options: xml.ParseOptions = {
  supportDoctype: true,
  ignoreNameSpace: true,
  tagValueCallbackFunction: tagFunc,
  attributeValueCallbackFunction: attFunc,
  tokenValueCallbackFunction: tokenFunc
};
that.parse(options);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

输出结果如下所示:

tag-
token-0 0
tag-book
attri-category COOKING
token-2 1
tag-title
attri-lang en
token-2 2
tag-Everyday
token-4 2
tag-title
token-3 2
tag-author
token-2 2
tag-Giada
token-4 2
tag-author
token-3 2
tag-book
token-3 1
tag-
token-1 0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

XML转换

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

语言基础类库提供ConvertXML类将XML文本转换为JavaScript对象,输入为待转换的XML字符串及转换选项,输出为转换后的JavaScript对象。具体转换选项可见 API参考@ohos.convertxml 。

注意事项

XML解析及转换需要确保传入的XML数据符合标准格式。

开发步骤

此处以XML转为JavaScript对象后获取其标签值为例,说明转换效果。

  1. 引入模块。
import { convertxml } from '@kit.ArkTS';
  • 1
  1. 输入待转换的XML,设置转换选项。
let xml: string =
 '' +
 '' +
 '    Happy' +
 '    Work' +
 '    Play' +
 '';
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"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  1. 调用转换函数,打印结果。
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);
  • 1
  • 2
  • 3
  • 4

输出结果如下所示:

strRes:
{"_declaration":{"_attributes":{"version":"1.0","encoding":"utf-8"}},"_elements":[{"_type":"element","_name":"note",
 "_attributes":{"importance":"high","logged":"true"},"_elements":[{"_type":"element","_name":"title",
 "_elements":[{"_type":"text","_text":"Happy"}]},{"_type":"element","_name":"todo",
 "_elements":[{"_type":"text","_text":"Work"}]},{"_type":"element","_name":"todo",
 "_elements":[{"_type":"text","_text":"Play"}]}]}]}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

鸿蒙全栈开发全新学习指南

为了积极培养鸿蒙生态人才,让大家都能学习到鸿蒙开发最新的技术,针对一些在职人员、0基础小白、应届生/计算机专业、鸿蒙爱好者等人群,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线【包含了大厂APP实战项目开发】。

本路线共分为四个阶段:

第一阶段:鸿蒙初中级开发必备技能

在这里插入图片描述

第二阶段:鸿蒙南北双向高工技能基础:gitee.com/MNxiaona/733GH

第三阶段:应用开发中高级就业技术

第四阶段:全网首发-工业级南向设备开发就业技术:gitee.com/MNxiaona/733GH

鸿蒙开发面试真题(含参考答案):gitee.com/MNxiaona/733GH

写在最后

  • 如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
  • 关注小编,同时可以期待后续文章ing?,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请移步前往小编:gitee.com/MNxiaona/733GH

文章知识点与官方知识档案匹配,可进一步学习相关知识
Python入门技能树首页概览450702 人正在系统学习中
鸿蒙开发学习资料领取!!!
微信名片
注:本文转载自blog.csdn.net的OpenHarmony_小贾的文章"https://blog.csdn.net/maniuT/article/details/140017805"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top