• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_xml.h"
17 #include "napi/native_api.h"
18 #include "napi/native_node_api.h"
19 
20 extern const char _binary_js_xml_js_start[];
21 extern const char _binary_js_xml_js_end[];
22 extern const char _binary_xml_abc_start[];
23 extern const char _binary_xml_abc_end[];
24 
25 namespace OHOS::xml {
XmlSerializerConstructor(napi_env env,napi_callback_info info)26     static napi_value XmlSerializerConstructor(napi_env env, napi_callback_info info)
27     {
28         napi_value thisVar = nullptr;
29         void *data = nullptr;
30         size_t argc = 0;
31         napi_value args[2] = { 0 }; // 2:The number of parameters is 2
32         XmlSerializer *object = nullptr;
33         size_t iLength = 0;
34         size_t offPos = 0;
35         napi_value arraybuffer = nullptr;
36         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data));
37         NAPI_ASSERT(env, argc == 1 || argc == 2, "Wrong number of arguments"); // 2: number of args
38         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, &data));
39         if (args[0] == nullptr) {
40             NAPI_CALL(env, napi_throw_error(env, "", "parameter is empty"));
41             return nullptr;
42         } else {
43             bool bFlag = false;
44             napi_is_arraybuffer(env, args[0], &bFlag);
45             if (bFlag) {
46                 napi_get_arraybuffer_info(env, args[0], &data, &iLength);
47             }
48             napi_is_dataview(env, args[0], &bFlag);
49             if (bFlag) {
50                 napi_get_dataview_info(env, args[0], &iLength, &data, &arraybuffer, &offPos);
51             }
52         }
53         if (argc == 1) {
54             object = new XmlSerializer(reinterpret_cast<char*>(data), iLength);
55         } else if (argc == 2) { // 2:When the input parameter is set to 2
56             std::string encoding = "";
57             napi_valuetype valuetype;
58             NAPI_CALL(env, napi_typeof(env, args[1], &valuetype));
59             NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected.");
60             napi_status status = napi_ok;
61             status = XmlSerializer::DealNapiStrValue(env, args[1], encoding);
62             if (status == napi_ok) {
63                 object = new XmlSerializer(reinterpret_cast<char*>(data), iLength, encoding);
64             }
65         }
66         napi_wrap(
67             env, thisVar, object,
68             [](napi_env environment, void *data, void *hint) {
69                 auto obj = reinterpret_cast<XmlSerializer*>(data);
70                 if (obj != nullptr) {
71                     delete obj;
72                 }
73             },
74             nullptr, nullptr);
75         return thisVar;
76     }
77 
XmlPullParserConstructor(napi_env env,napi_callback_info info)78     static napi_value XmlPullParserConstructor(napi_env env, napi_callback_info info)
79     {
80         napi_value thisVar = nullptr;
81         void *data = nullptr;
82         size_t argc = 0;
83         napi_value args[2] = { 0 }; // 2:two args
84         XmlPullParser *object = nullptr;
85         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, &data));
86         NAPI_ASSERT(env, argc == 1 || argc == 2, "Wrong number of arguments"); // 2:two args
87         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, &data));
88         napi_valuetype valuetype = napi_null;
89         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
90         NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument typr. Object(DataView or ArrayBuffer) expected.");
91         bool bFlag = false;
92         size_t len = 0;
93         size_t offPos = 0;
94         napi_value arraybuffer = nullptr;
95         NAPI_ASSERT(env, args[0] != nullptr, "Wrong argument value. (not nullptr expected).");
96         napi_is_arraybuffer(env, args[0], &bFlag);
97         if (bFlag) {
98             napi_get_arraybuffer_info(env, args[0], &data, &len);
99         }
100         napi_is_dataview(env, args[0], &bFlag);
101         if (bFlag) {
102             napi_get_dataview_info(env, args[0], &len, &data, &arraybuffer, &offPos);
103         }
104         if (data) {
105             std::string strEnd(reinterpret_cast<char*>(data), len);
106             strEnd = strEnd.substr(0, std::strlen(strEnd.c_str()));
107             if (argc == 1) {
108                 object = new XmlPullParser(strEnd, "utf-8");
109             } else if (argc == 2) { // 2:When the input parameter is set to 2
110                 NAPI_CALL(env, napi_typeof(env, args[1], &valuetype));
111                 NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected.");
112                 std::string strEncoding = "";
113                 XmlSerializer::DealNapiStrValue(env, args[1], strEncoding);
114                 object = new XmlPullParser(strEnd, strEncoding);
115             }
116         }
117         napi_wrap(
118             env, thisVar, object,
119             [](napi_env env, void *data, void *hint) {
120                 auto obj = reinterpret_cast<XmlPullParser*>(data);
121                 if (obj != nullptr) {
122                     delete obj;
123                 }
124             },
125             nullptr, nullptr);
126         return thisVar;
127     }
128 
SetAttributes(napi_env env,napi_callback_info info)129     static napi_value SetAttributes(napi_env env, napi_callback_info info)
130     {
131         napi_value thisVar = nullptr;
132         size_t argc = 0;
133         napi_value args[2] = { 0 }; // 2:two args
134         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
135         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
136         NAPI_ASSERT(env, argc == 2, "Wrong number of arguments"); // 2: number of args
137         napi_valuetype valuetype = napi_null;
138         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty.");
139         NAPI_ASSERT(env, args[1] != nullptr, "Parameter is empty.");
140         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
141         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected.");
142         NAPI_CALL(env, napi_typeof(env, args[1], &valuetype));
143         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected.");
144         XmlSerializer *object = nullptr;
145         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
146         std::string name;
147         std::string value;
148         XmlSerializer::DealNapiStrValue(env, args[0], name);
149         XmlSerializer::DealNapiStrValue(env, args[1], value);
150         object->SetAttributes(name, value);
151         napi_value result = nullptr;
152         NAPI_CALL(env, napi_get_undefined(env, &result));
153         return result;
154     }
155 
AddEmptyElement(napi_env env,napi_callback_info info)156     static napi_value AddEmptyElement(napi_env env, napi_callback_info info)
157     {
158         napi_value thisVar = nullptr;
159         size_t argc = 1;
160         napi_value args[1] = { 0 };
161         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
162         NAPI_ASSERT(env, argc == 1, "Wrong number of arguments(Over)");
163         if (args[0] == nullptr) {
164             NAPI_CALL(env, napi_throw_error(env, "", "parameter is empty"));
165             return nullptr;
166         } else {
167             napi_valuetype valuetype;
168             NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
169             NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected.");
170             XmlSerializer *object = nullptr;
171             NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
172             std::string name;
173             object->DealNapiStrValue(env, args[0], name);
174             object->AddEmptyElement(name);
175         }
176         napi_value result = nullptr;
177         NAPI_CALL(env, napi_get_undefined(env, &result));
178         return result;
179     }
180 
SetDeclaration(napi_env env,napi_callback_info info)181     static napi_value SetDeclaration(napi_env env, napi_callback_info info)
182     {
183         napi_value thisVar = nullptr;
184         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
185         XmlSerializer *object = nullptr;
186         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
187         object->SetDeclaration();
188         napi_value result = nullptr;
189         NAPI_CALL(env, napi_get_undefined(env, &result));
190         return result;
191     }
192 
StartElement(napi_env env,napi_callback_info info)193     static napi_value StartElement(napi_env env, napi_callback_info info)
194     {
195         size_t argc = 1;
196         napi_value args[1] = { 0 };
197         napi_value thisVar = nullptr;
198         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
199         NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
200         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
201         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty.");
202         XmlSerializer *object = nullptr;
203         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
204         std::string name;
205         object->DealNapiStrValue(env, args[0], name);
206         object->StartElement(name);
207         napi_value result = nullptr;
208         NAPI_CALL(env, napi_get_undefined(env, &result));
209         return result;
210     }
211 
EndElement(napi_env env,napi_callback_info info)212     static napi_value EndElement(napi_env env, napi_callback_info info)
213     {
214         napi_value thisVar = nullptr;
215         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
216         XmlSerializer *object = nullptr;
217         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
218         object->EndElement();
219         napi_value result = nullptr;
220         NAPI_CALL(env, napi_get_undefined(env, &result));
221         return result;
222     }
223 
SetNamespace(napi_env env,napi_callback_info info)224     static napi_value SetNamespace(napi_env env, napi_callback_info info)
225     {
226         napi_value thisVar = nullptr;
227         size_t argc = 0;
228         napi_value args[2] = { 0 }; // 2:two args
229         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
230         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
231         NAPI_ASSERT(env, argc == 2, "Wrong number of arguments"); // 2:two args
232         napi_valuetype valuetype = napi_null;
233         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty.");
234         NAPI_ASSERT(env, args[1] != nullptr, "Parameter is empty.");
235         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
236         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected.");
237         NAPI_CALL(env, napi_typeof(env, args[1], &valuetype));
238         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. Object expected.");
239         XmlSerializer *object = nullptr;
240         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
241         std::string prefix;
242         std::string nsTemp;
243         XmlSerializer::DealNapiStrValue(env, args[0], prefix);
244         XmlSerializer::DealNapiStrValue(env, args[1], nsTemp);
245         object->SetNamespace(prefix, nsTemp);
246         napi_value result = nullptr;
247         NAPI_CALL(env, napi_get_undefined(env, &result));
248         return result;
249     }
250 
SetComment(napi_env env,napi_callback_info info)251     static napi_value SetComment(napi_env env, napi_callback_info info)
252     {
253         napi_value thisVar = nullptr;
254         size_t argc = 0;
255         napi_value args[1] = { 0 };
256         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
257         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
258         NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
259         napi_valuetype valuetype = napi_null;
260         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty).");
261         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
262         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected");
263         XmlSerializer *object = nullptr;
264         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
265         std::string comment;
266         object->DealNapiStrValue(env, args[0], comment);
267         object->SetComment(comment);
268         napi_value result = nullptr;
269         NAPI_CALL(env, napi_get_undefined(env, &result));
270         return result;
271     }
272 
SetCData(napi_env env,napi_callback_info info)273     static napi_value SetCData(napi_env env, napi_callback_info info)
274     {
275         napi_value thisVar = nullptr;
276         size_t argc = 0;
277         napi_value args[1] = { 0 };
278         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
279         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
280         NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
281         napi_valuetype valuetype = napi_null;
282         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty).");
283         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
284         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected");
285         XmlSerializer *object = nullptr;
286         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
287         std::string data;
288         XmlSerializer::DealNapiStrValue(env, args[0], data);
289         object->SetCData(data);
290         napi_value result = nullptr;
291         NAPI_CALL(env, napi_get_undefined(env, &result));
292         return result;
293     }
294 
SetText(napi_env env,napi_callback_info info)295     static napi_value SetText(napi_env env, napi_callback_info info)
296     {
297         napi_value thisVar = nullptr;
298         size_t argc = 0;
299         napi_value args[1] = { 0 };
300         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
301         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
302         NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
303         napi_valuetype valuetype = napi_null;
304         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty).");
305         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
306         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected.");
307         XmlSerializer *object = nullptr;
308         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
309         std::string text;
310         XmlSerializer::DealNapiStrValue(env, args[0], text);
311         object->SetText(text);
312         napi_value result = nullptr;
313         NAPI_CALL(env, napi_get_undefined(env, &result));
314         return result;
315     }
316 
SetDocType(napi_env env,napi_callback_info info)317     static napi_value SetDocType(napi_env env, napi_callback_info info)
318     {
319         napi_value thisVar = nullptr;
320         size_t argc = 0;
321         napi_value args[1] = { 0 };
322         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
323         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
324         NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
325         napi_valuetype valuetype = napi_null;
326         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty).");
327         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
328         NAPI_ASSERT(env, valuetype == napi_string, "Wrong argument typr. String expected.");
329         XmlSerializer *object = nullptr;
330         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
331         std::string text;
332         XmlSerializer::DealNapiStrValue(env, args[0], text);
333         object->SetDocType(text);
334         napi_value result = nullptr;
335         NAPI_CALL(env, napi_get_undefined(env, &result));
336         return result;
337     }
XmlSerializerError(napi_env env,napi_callback_info info)338     static napi_value XmlSerializerError(napi_env env, napi_callback_info info)
339     {
340         napi_value thisVar = nullptr;
341         napi_value result = nullptr;
342         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
343         XmlSerializer *object = nullptr;
344         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
345         std::string temp = object->XmlSerializerError();
346         size_t templen = temp.size();
347         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
348         return result;
349     }
350 
XmlSerializerInit(napi_env env,napi_value exports)351     static napi_value XmlSerializerInit(napi_env env, napi_value exports)
352     {
353         const char *xmlSerializerClass = "XmlSerializer";
354         napi_value xmlClass = nullptr;
355         napi_property_descriptor xmlDesc[] = {
356             DECLARE_NAPI_FUNCTION("setAttributes", SetAttributes),
357             DECLARE_NAPI_FUNCTION("addEmptyElement", AddEmptyElement),
358             DECLARE_NAPI_FUNCTION("setDeclaration", SetDeclaration),
359             DECLARE_NAPI_FUNCTION("startElement", StartElement),
360             DECLARE_NAPI_FUNCTION("endElement", EndElement),
361             DECLARE_NAPI_FUNCTION("setNamespace", SetNamespace),
362             DECLARE_NAPI_FUNCTION("setComment", SetComment),
363             DECLARE_NAPI_FUNCTION("setCDATA", SetCData),
364             DECLARE_NAPI_FUNCTION("setText", SetText),
365             DECLARE_NAPI_FUNCTION("setDocType", SetDocType),
366             DECLARE_NAPI_FUNCTION("XmlSerializerError", XmlSerializerError)
367         };
368         NAPI_CALL(env, napi_define_class(env, xmlSerializerClass, strlen(xmlSerializerClass), XmlSerializerConstructor,
369                                          nullptr, sizeof(xmlDesc) / sizeof(xmlDesc[0]), xmlDesc, &xmlClass));
370         napi_property_descriptor desc[] = {
371             DECLARE_NAPI_PROPERTY("XmlSerializer", xmlClass)
372         };
373         napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
374         return exports;
375     }
376 
Parse(napi_env env,napi_callback_info info)377     static napi_value Parse(napi_env env, napi_callback_info info)
378     {
379         napi_value thisVar = nullptr;
380         size_t argc = 0;
381         napi_value args[1] = { 0 };
382         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr));
383         NAPI_ASSERT(env, argc == 1, "Wrong number of arguments, one expected.");
384         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, &thisVar, nullptr));
385         NAPI_ASSERT(env, args[0] != nullptr, "Parameter is empty.");
386         napi_valuetype valuetype;
387         NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
388         NAPI_ASSERT(env, valuetype == napi_object, "Wrong argument typr. Object expected.");
389         XmlPullParser *object = nullptr;
390         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
391         object->DealOptionInfo(env, args[0]);
392         object->Parse(env, thisVar);
393         napi_value result = nullptr;
394         NAPI_CALL(env, napi_get_undefined(env, &result));
395         return result;
396     }
397 
XmlPullParserError(napi_env env,napi_callback_info info)398     static napi_value XmlPullParserError(napi_env env, napi_callback_info info)
399     {
400         napi_value thisVar = nullptr;
401         napi_value result = nullptr;
402         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
403         XmlPullParser *object = nullptr;
404         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&object)));
405         std::string temp = object->XmlPullParserError();
406         size_t templen = temp.size();
407         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
408         return result;
409     }
410 
XmlPullParserInit(napi_env env,napi_value exports)411     static napi_value XmlPullParserInit(napi_env env, napi_value exports)
412     {
413         const char *xmlPullParserClass = "XmlPullParser";
414         napi_value xmlClass = nullptr;
415         napi_property_descriptor xmlDesc[] = {
416             DECLARE_NAPI_FUNCTION("parse", Parse),
417             DECLARE_NAPI_FUNCTION("XmlPullParserError", XmlPullParserError)
418         };
419         NAPI_CALL(env, napi_define_class(env, xmlPullParserClass, strlen(xmlPullParserClass),
420             XmlPullParserConstructor, nullptr, sizeof(xmlDesc) / sizeof(xmlDesc[0]),
421             xmlDesc, &xmlClass));
422         napi_property_descriptor desc[] = {
423             DECLARE_NAPI_PROPERTY("XmlPullParser", xmlClass)
424         };
425         napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
426         return exports;
427     };
428 
Init(napi_env env,napi_value exports)429     static napi_value Init(napi_env env, napi_value exports)
430     {
431         XmlSerializerInit(env, exports);
432         XmlPullParserInit(env, exports);
433         return exports;
434     }
435 
436     extern "C"
NAPI_xml_GetJSCode(const char ** buf,int * bufLen)437     __attribute__((visibility("default"))) void NAPI_xml_GetJSCode(const char **buf, int *bufLen)
438     {
439         if (buf != nullptr) {
440             *buf = _binary_js_xml_js_start;
441         }
442 
443         if (bufLen != nullptr) {
444             *bufLen = _binary_js_xml_js_end - _binary_js_xml_js_start;
445         }
446     }
447     extern "C"
NAPI_xml_GetABCCode(const char ** buf,int * buflen)448     __attribute__((visibility("default"))) void NAPI_xml_GetABCCode(const char** buf, int* buflen)
449     {
450         if (buf != nullptr) {
451             *buf = _binary_xml_abc_start;
452         }
453         if (buflen != nullptr) {
454             *buflen = _binary_xml_abc_end - _binary_xml_abc_start;
455         }
456     }
457 
458 
459     static napi_module xmlModule = {
460         .nm_version = 1,
461         .nm_flags = 0,
462         .nm_filename = nullptr,
463         .nm_register_func = Init,
464         .nm_modname = "xml",
465         .nm_priv = reinterpret_cast<void*>(0),
466         .reserved = {0},
467     };
RegisterModule()468     extern "C" __attribute__((constructor)) void RegisterModule()
469     {
470         napi_module_register(&xmlModule);
471     }
472 } // namespace OHOS::Xml
473