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