1# XML解析 2 3 4对于以XML作为载体传递的数据,实际使用中需要对相关的节点进行解析,一般包括[解析XML标签和标签值](#解析xml标签和标签值)、[解析XML属性和属性值](#解析xml属性和属性值)、[解析XML事件类型和元素深度](#解析xml事件类型和元素深度)三类操作。如在Web服务中,XML是SOAP(Simple Object Access Protocol)协议的基础,SOAP消息通常以XML格式封装,包含请求和响应参数,通过解析这些XML消息,Web服务可以处理来自客户端的请求并生成相应的响应。 5 6 7XML模块提供XmlPullParser类对XML文件解析,输入为含有XML文本的ArrayBuffer或DataView,输出为解析得到的信息。 8 9 10 **表1** XML解析选项,其详细介绍请参见[ParseOptions](../reference/apis-arkts/js-apis-xml.md#parseoptions)。 11 12| 名称 | 类型 | 必填 | 说明 | 13| -------- | -------- | -------- | -------- | 14| supportDoctype | boolean | 否 | 是否忽略文档类型。默认为false,表示不解析文档类型。 | 15| ignoreNameSpace | boolean | 否 | 是否忽略命名空间。默认为false,表示对命名空间进行解析。 | 16| tagValueCallbackFunction | (name: string, value: string) => boolean | 否 | 获取tagValue回调函数,打印标签及标签值。默认为null,表示不进行XML标签和标签值的解析。 | 17| attributeValueCallbackFunction | (name: string, value: string) => boolean | 否 | 获取attributeValue回调函数, 打印属性及属性值。默认为null,表示不进行XML属性和属性值的解析。 | 18| tokenValueCallbackFunction | (eventType: EventType, value: ParseInfo) => boolean | 否 | 获取tokenValue回调函数,打印标签事件类型及parseInfo对应属性。默认为null,表示不进行XML事件类型解析。 | 19 20 21## 注意事项 22 23- XML解析及转换需要确保传入的XML数据符合标准格式。 24 25- XML解析目前不支持按指定节点解析对应的节点值。 26 27 28## 解析XML标签和标签值 29 301. 引入模块。 31 32 ```ts 33 import { xml, util } from '@kit.ArkTS'; // 需要使用util模块函数对文件编码 34 ``` 35 362. 对XML文件编码后调用XmlPullParser。 37 38 可以基于ArrayBuffer构造XmlPullParser对象, 也可以基于DataView构造XmlPullParser对象(两种构造方式返回结果无区别可任选一种)。 39 40 ```ts 41 let strXml: string = 42 '<?xml version="1.0" encoding="utf-8"?>' + 43 '<note importance="high" logged="true">' + 44 '<title>Play</title>' + 45 '<lens>Work</lens>' + 46 '</note>'; 47 let textEncoder: util.TextEncoder = new util.TextEncoder(); 48 let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); // 对数据编码,防止包含中文字符乱码 49 // 方式1:基于ArrayBuffer构造XmlPullParser对象 50 let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8'); 51 52 // 方式2:基于DataView构造XmlPullParser对象 53 // let dataView: DataView = new DataView(arrBuffer.buffer as object as ArrayBuffer); 54 // let that: xml.XmlPullParser = new xml.XmlPullParser(dataView, 'UTF-8'); 55 ``` 56 573. 自定义回调函数,本例直接打印出标签及标签值。 58 59 ```ts 60 function func(name: string, value: string): boolean { 61 if (name == 'note') { 62 console.info(name); 63 } 64 if (value == 'Play' || value == 'Work') { 65 console.info(' ' + value); 66 } 67 if (name == 'title' || name == 'lens') { 68 console.info(' ' + name); 69 } 70 return true; //true:继续解析 false:停止解析 71 } 72 ``` 73 744. 设置解析选项,调用parse函数。 75 76 ```ts 77 let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, tagValueCallbackFunction:func}; 78 that.parse(options); 79 ``` 80 81 输出结果如下所示: 82 83 ``` 84 note 85 title 86 Play 87 title 88 lens 89 Work 90 lens 91 note 92 ``` 93 94 95 96 97## 解析XML属性和属性值 98 991. 引入模块。 100 101 ```ts 102 import { xml, util } from '@kit.ArkTS'; // 需要使用util模块函数对文件编码 103 ``` 104 1052. 对XML文件编码后调用XmlPullParser。 106 107 ```ts 108 let strXml: string = 109 '<?xml version="1.0" encoding="utf-8"?>' + 110 '<note importance="high" logged="true">' + 111 ' <title>Play</title>' + 112 ' <title>Happy</title>' + 113 ' <lens>Work</lens>' + 114 '</note>'; 115 let textEncoder: util.TextEncoder = new util.TextEncoder(); 116 let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); // 对数据编码,防止包含中文字符乱码 117 let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8'); 118 ``` 119 1203. 自定义回调函数,本例直接打印出属性及属性值。 121 122 ```ts 123 let str: string = ''; 124 function func(name: string, value: string): boolean { 125 str += name + ' ' + value + ' '; 126 return true; // true:继续解析 false:停止解析 127 } 128 ``` 129 1304. 设置解析选项,调用parse函数。 131 132 ```ts 133 let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, attributeValueCallbackFunction:func}; 134 that.parse(options); 135 console.info(str); // 一次打印出所有的属性及其值 136 ``` 137 138 输出结果如下所示: 139 ``` 140 importance high logged true // note节点的属性及属性值 141 ``` 142 143 144## 解析XML事件类型和元素深度 145 1461. 引入模块。 147 148 ```ts 149 import { xml, util } from '@kit.ArkTS'; // 需要使用util模块函数对文件编码 150 ``` 151 1522. 对XML文件编码后调用XmlPullParser。 153 154 ```ts 155 let strXml: string = 156 '<?xml version="1.0" encoding="utf-8"?>' + 157 '<note importance="high" logged="true">' + 158 '<title>Play</title>' + 159 '</note>'; 160 let textEncoder: util.TextEncoder = new util.TextEncoder(); 161 let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); // 对数据编码,防止包含中文字符乱码 162 let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8'); 163 ``` 164 1653. 自定义回调函数,本例直接打印元素事件类型及元素深度。 166 167 ```ts 168 let str: string = ''; 169 function func(name: xml.EventType, value: xml.ParseInfo): boolean { 170 str = name + ' ' + value.getDepth(); // getDepth 获取元素的当前深度 171 console.info(str) 172 return true; //true:继续解析 false:停止解析 173 } 174 ``` 175 1764. 设置解析选项,调用parse函数。 177 178 ```ts 179 let options: xml.ParseOptions = {supportDoctype:true, ignoreNameSpace:true, tokenValueCallbackFunction:func}; 180 that.parse(options); 181 ``` 182 183 输出结果如下所示: 184 185 ``` 186 0 0 // 0:<?xml version="1.0" encoding="utf-8"?> 对应事件类型 START_DOCUMENT值为0 0:起始深度为0 187 2 1 // 2:<note importance="high" logged="true"> 对应事件类型START_TAG值为2 1:深度为1 188 2 2 // 2:<title>对应事件类型START_TAG值为2 2:深度为2 189 4 2 // 4:Play对应事件类型TEXT值为4 2:深度为2 190 3 2 // 3:</title>对应事件类型END_TAG值为3 2:深度为2 191 3 1 // 3:</note>对应事件类型END_TAG值为3 1:深度为1(与<note对应>) 192 1 0 // 1:对应事件类型END_DOCUMENT值为1 0:深度为0 193 ``` 194 195 196 197 198## 场景示例 199 200此处以调用所有解析选项为例,提供解析XML标签、属性和事件类型的开发示例。 201 202 203```ts 204import { xml, util } from '@kit.ArkTS'; 205 206let strXml: string = 207 '<?xml version="1.0" encoding="UTF-8"?>' + 208 '<book category="COOKING">' + 209 '<title lang="en">Everyday</title>' + 210 '<author>Giana</author>' + 211 '</book>'; 212let textEncoder: util.TextEncoder = new util.TextEncoder(); 213let arrBuffer: Uint8Array = textEncoder.encodeInto(strXml); 214let that: xml.XmlPullParser = new xml.XmlPullParser(arrBuffer.buffer as object as ArrayBuffer, 'UTF-8'); 215let str: string = ''; 216 217function tagFunc(name: string, value: string): boolean { 218 str = name + value; 219 console.info('tag-' + str); 220 return true; 221} 222 223function attFunc(name: string, value: string): boolean { 224 str = name + ' ' + value; 225 console.info('attri-' + str); 226 return true; 227} 228 229function tokenFunc(name: xml.EventType, value: xml.ParseInfo): boolean { 230 str = name + ' ' + value.getDepth(); 231 console.info('token-' + str); 232 return true; 233} 234 235let options: xml.ParseOptions = { 236 supportDoctype: true, 237 ignoreNameSpace: true, 238 tagValueCallbackFunction: tagFunc, 239 attributeValueCallbackFunction: attFunc, 240 tokenValueCallbackFunction: tokenFunc 241}; 242that.parse(options); 243``` 244 245输出结果如下所示: 246 247 ``` 248 tag- 249 token-0 0 250 tag-book 251 attri-category COOKING 252 token-2 1 253 tag-title 254 attri-lang en 255 token-2 2 256 tag-Everyday 257 token-4 2 258 tag-title 259 token-3 2 260 tag-author 261 token-2 2 262 tag-Giana 263 token-4 2 264 tag-author 265 token-3 2 266 tag-book 267 token-3 1 268 tag- 269 token-1 0 270 ``` 271