• 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_convertxml.h"
17 #include "tools/log.h"
18 namespace OHOS::Xml {
GetNodeType(const xmlElementType enumType) const19     std::string ConvertXml::GetNodeType(const xmlElementType enumType) const
20     {
21         std::string strResult = "";
22         switch (enumType) {
23             case xmlElementType::XML_ELEMENT_NODE:
24                 strResult = "element";
25                 break;
26             case xmlElementType::XML_ATTRIBUTE_NODE:
27                 strResult = "attribute";
28                 break;
29             case xmlElementType::XML_TEXT_NODE:
30                 strResult = "text";
31                 break;
32             case xmlElementType::XML_CDATA_SECTION_NODE:
33                 strResult = "cdata";
34                 break;
35             case xmlElementType::XML_ENTITY_REF_NODE:
36                 strResult = "entity_ref";
37                 break;
38             case xmlElementType::XML_ENTITY_NODE:
39                 strResult = "entity";
40                 break;
41             case xmlElementType::XML_PI_NODE:
42                 strResult = "instruction";
43                 break;
44             case xmlElementType::XML_COMMENT_NODE:
45                 strResult = "comment";
46                 break;
47             case xmlElementType::XML_DOCUMENT_NODE:
48                 strResult = "document";
49                 break;
50             case xmlElementType::XML_DOCUMENT_TYPE_NODE:
51                 strResult = "document_type";
52                 break;
53             case xmlElementType::XML_DOCUMENT_FRAG_NODE:
54                 strResult = "document_frag";
55                 break;
56             case xmlElementType::XML_DTD_NODE:
57                 strResult = "doctype";
58                 break;
59 #ifdef LIBXML_DOCB_ENABLED
60             case xmlElementType::XML_DOCB_DOCUMENT_NODE:
61                 strResult =  "docb_document";
62                 break;
63 #endif
64             default:
65                 break;
66         }
67         return strResult;
68     }
69 
SetKeyValue(napi_env env,const napi_value & object,const std::string strKey,const std::string strValue) const70     void ConvertXml::SetKeyValue(napi_env env, const napi_value &object, const std::string strKey,
71                                  const std::string strValue) const
72     {
73         napi_value attrValue = nullptr;
74         napi_create_string_utf8(env, strValue.c_str(), NAPI_AUTO_LENGTH, &attrValue);
75         napi_set_named_property(env, object, strKey.c_str(), attrValue);
76     }
Trim(std::string strXmltrim) const77     std::string ConvertXml::Trim(std::string strXmltrim) const
78     {
79         if (strXmltrim.empty()) {
80             return "";
81         }
82         size_t i = 0;
83         size_t strlen = strXmltrim.size();
84         for (; i < strlen;) {
85             if (strXmltrim[i] == ' ') {
86                 i++;
87             } else {
88                 break;
89             }
90         }
91         strXmltrim = strXmltrim.substr(i);
92         strlen = strXmltrim.size();
93         for (i = strlen - 1; i != 0; i--) {
94             if (strXmltrim[i] == ' ') {
95                 strXmltrim.pop_back();
96             } else {
97                 break;
98             }
99         }
100         return strXmltrim;
101     }
102 
GetPrevNodeList(napi_env env,xmlNodePtr curNode)103     void ConvertXml::GetPrevNodeList(napi_env env, xmlNodePtr curNode)
104     {
105         while (curNode->prev != nullptr) {
106             curNode = curNode->prev;
107             napi_value elementsObject = nullptr;
108             napi_create_object(env, &elementsObject);
109             char *curContent = nullptr;
110             if (curNode->type == xmlElementType::XML_PI_NODE && !options_.ignoreInstruction) {
111                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
112                 SetKeyValue(env, elementsObject, options_.name, reinterpret_cast<const char*>(curNode->name));
113                 curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
114                 if (curContent != nullptr) {
115                     SetKeyValue(env, elementsObject, options_.instruction, curContent);
116                     xmlFree(reinterpret_cast<void*>(curContent));
117                 }
118                 prevObj_.push_back(elementsObject);
119             }
120             if (curNode->type == xmlElementType::XML_COMMENT_NODE && !options_.ignoreComment) {
121                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
122                 curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
123                 if (curContent != nullptr) {
124                     SetKeyValue(env, elementsObject, options_.comment, curContent);
125                     xmlFree(reinterpret_cast<void*>(curContent));
126                 }
127                 prevObj_.push_back(elementsObject);
128             }
129             if (curNode->type == xmlElementType::XML_DTD_NODE && !options_.ignoreDoctype) {
130                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
131                 SetKeyValue(env, elementsObject, options_.doctype,
132                             reinterpret_cast<const char*>(curNode->name));
133                 prevObj_.push_back(elementsObject);
134             }
135         }
136     }
137 
SetAttributes(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject) const138     void ConvertXml::SetAttributes(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject) const
139     {
140         if (curNode->type == XML_ENTITY_DECL) {
141             return;
142         }
143         xmlAttr *attr = curNode->properties;
144         if (attr && !options_.ignoreAttributes) {
145             napi_value attrTitleObj = nullptr;
146             napi_create_object(env, &attrTitleObj);
147             while (attr) {
148                 SetKeyValue(env, attrTitleObj, reinterpret_cast<const char*>(attr->name),
149                             reinterpret_cast<const char*>(attr->children->content));
150                 attr = attr->next;
151             }
152             napi_set_named_property(env, elementsObject, options_.attributes.c_str(), attrTitleObj);
153         }
154     }
155 
SetXmlElementType(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject,bool & bFlag) const156     void ConvertXml::SetXmlElementType(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
157                                        bool &bFlag) const
158     {
159         char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
160         if (curNode->type == xmlElementType::XML_PI_NODE && !options_.ignoreInstruction) {
161             if (curContent != nullptr) {
162                 SetKeyValue(env, elementsObject, options_.instruction, curContent);
163                 bFlag = true;
164             }
165         } else if (curNode->type == xmlElementType::XML_COMMENT_NODE && !options_.ignoreComment) {
166             if (curContent != nullptr) {
167                 SetKeyValue(env, elementsObject, options_.comment, curContent);
168                 bFlag = true;
169             }
170         } else if (curNode->type == xmlElementType::XML_CDATA_SECTION_NODE && !options_.ignoreCdata) {
171             if (curContent != nullptr) {
172                 SetKeyValue(env, elementsObject, options_.cdata, curContent);
173                 bFlag = true;
174             }
175         }
176         if (curContent != nullptr) {
177             xmlFree(reinterpret_cast<void*>(curContent));
178         }
179     }
180 
SetNodeInfo(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject,const std::string parentName) const181     void ConvertXml::SetNodeInfo(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
182                                  const std::string parentName) const
183     {
184         if (curNode->type == xmlElementType::XML_TEXT_NODE) {
185             return;
186         }
187         if (curNode->type == xmlElementType::XML_PI_NODE) {
188             if (!options_.ignoreInstruction) {
189                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
190             }
191         } else {
192                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
193         }
194         if ((curNode->type != xmlElementType::XML_COMMENT_NODE) &&
195             (curNode->type != xmlElementType::XML_CDATA_SECTION_NODE)) {
196             if (!(curNode->type == xmlElementType::XML_PI_NODE && options_.ignoreInstruction)) {
197                 SetKeyValue(env, elementsObject, options_.name, reinterpret_cast<const char*>(curNode->name));
198                 if (!parentName.empty()) {
199                     SetKeyValue(env, elementsObject, options_.parent, parentName);
200                 }
201             }
202         }
203     }
204 
SetEndInfo(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject,bool & bFlag) const205     void ConvertXml::SetEndInfo(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
206                                 bool &bFlag) const
207     {
208         SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
209         if (curNode->type == xmlElementType::XML_ELEMENT_NODE) {
210             SetKeyValue(env, elementsObject, options_.name, reinterpret_cast<const char*>(curNode->name));
211             bFlag = true;
212         } else if (curNode->type == xmlElementType::XML_TEXT_NODE) {
213             char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
214             if (options_.trim) {
215                 if (curContent != nullptr) {
216                     SetKeyValue(env, elementsObject, options_.text,
217                                 Trim(curContent));
218                 }
219             } else {
220                 if (curContent != nullptr) {
221                     SetKeyValue(env, elementsObject, options_.text, curContent);
222                 }
223             }
224             if (curContent != nullptr) {
225                 xmlFree(reinterpret_cast<void*>(curContent));
226             }
227             if (!options_.ignoreText) {
228                 bFlag = true;
229             }
230         }
231     }
232 
SetPrevInfo(napi_env env,const napi_value & recvElement,int flag,int32_t & index1) const233     void ConvertXml::SetPrevInfo(napi_env env, const napi_value &recvElement, int flag, int32_t &index1) const
234     {
235         if (!prevObj_.empty() && !flag) {
236             for (size_t i = (prevObj_.size() - 1); i > 0; --i) {
237                 napi_set_element(env, recvElement, index1++, prevObj_[i]);
238             }
239             napi_set_element(env, recvElement, index1++, prevObj_[0]);
240         }
241     }
242 
GetXMLInfo(napi_env env,xmlNodePtr curNode,const napi_value & object,int flag,const std::string parentName)243     void ConvertXml::GetXMLInfo(napi_env env, xmlNodePtr curNode, const napi_value &object,
244                                 int flag, const std::string parentName)
245     {
246         napi_value recvElement = nullptr;
247         napi_create_array(env, &recvElement);
248         xmlNodePtr pNode = curNode;
249         int32_t index = 0;
250         bool bFlag = false;
251         while (pNode != nullptr) {
252             if (!deprecated_) {
253                 if (pNode->type == xmlElementType::XML_TEXT_NODE &&
254                     (pNode->next != nullptr || pNode->prev != nullptr)) {
255                     pNode = pNode->next;
256                     continue;
257                 }
258             }
259             bFlag = false;
260             napi_value elementsObject = nullptr;
261             napi_create_object(env, &elementsObject);
262             SetNodeInfo(env, pNode, elementsObject, parentName);
263             SetAttributes(env, pNode, elementsObject);
264             char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(pNode));
265             if (curContent != nullptr) {
266                 if (pNode->children != nullptr) {
267                     curNode = pNode->children;
268                     const std::string parentNameTemp = apiFlag_ ? reinterpret_cast<const char*>(pNode->name) : "";
269                     GetXMLInfo(env, curNode, elementsObject, 1, parentNameTemp);
270                     bFlag = true;
271                 } else {
272                     SetXmlElementType(env, pNode, elementsObject, bFlag);
273                     SetEndInfo(env, pNode, elementsObject, bFlag);
274                 }
275                 xmlFree(reinterpret_cast<void*>(curContent));
276             }
277             SetPrevInfo(env, recvElement, flag, index);
278             if (elementsObject != nullptr && bFlag) {
279                 napi_set_element(env, recvElement, index++, elementsObject);
280                 elementsObject = nullptr;
281             }
282             pNode = pNode->next;
283         }
284         if (bFlag) {
285             napi_set_named_property(env, object, options_.elements.c_str(), recvElement);
286         }
287     }
288 
SetSpacesInfo(napi_env env,const napi_value & object) const289     void ConvertXml::SetSpacesInfo(napi_env env, const napi_value &object) const
290     {
291         napi_value iTemp = nullptr;
292         switch (spaceType_) {
293             case (SpaceType::T_INT32):
294                 napi_create_int32(env, iSpace_, &iTemp);
295                 napi_set_named_property(env, object, "spaces", iTemp);
296                 break;
297             case (SpaceType::T_STRING):
298                 SetKeyValue(env, object, "spaces", strSpace_);
299                 break;
300             case (SpaceType::T_INIT):
301                 SetKeyValue(env, object, "spaces", strSpace_);
302                 break;
303             default:
304                 break;
305             }
306     }
307 
Convert(napi_env env,std::string strXml,bool deprecated)308     napi_value ConvertXml::Convert(napi_env env, std::string strXml, bool deprecated)
309     {
310         xmlNodePtr curNode = nullptr;
311         napi_value object = nullptr;
312         napi_status status = napi_create_object(env, &object);
313         if (status != napi_ok) {
314             return nullptr;
315         }
316         size_t len = strXml.size();
317         xmlDocPtr doc = xmlParseMemory(strXml.c_str(), len);
318         deprecated_ = deprecated;
319         if (!doc) {
320             xmlFreeDoc(doc);
321             DealSingleLine(env, strXml, object);
322             return object;
323         }
324         napi_value subObject = nullptr;
325         napi_value subSubObject = nullptr;
326         napi_create_object(env, &subSubObject);
327         napi_create_object(env, &subObject);
328         if (doc != nullptr && doc->version != nullptr) {
329             SetKeyValue(env, subSubObject, "version", (const char*)doc->version);
330         }
331         if (doc != nullptr && doc->encoding != nullptr) {
332             SetKeyValue(env, subSubObject, "encoding", (const char*)doc->encoding);
333         }
334         if (!options_.ignoreDeclaration && strXml.find("xml") != std::string::npos) {
335             napi_set_named_property(env, subObject, options_.attributes.c_str(), subSubObject);
336             napi_set_named_property(env, object, options_.declaration.c_str(), subObject);
337         }
338         if (doc != nullptr) {
339             curNode = xmlDocGetRootElement(doc);
340             GetPrevNodeList(env, curNode);
341             GetXMLInfo(env, curNode, object, 0);
342         }
343         xmlFreeDoc(doc);
344         if (deprecated_) {
345             SetSpacesInfo(env, object);
346         }
347         return object;
348     }
349 
DealNapiStrValue(napi_env env,const napi_value napi_StrValue,std::string & result) const350     napi_status ConvertXml::DealNapiStrValue(napi_env env, const napi_value napi_StrValue, std::string &result) const
351     {
352         std::string buffer = "";
353         size_t bufferSize = 0;
354         napi_status status = napi_ok;
355         status = napi_get_value_string_utf8(env, napi_StrValue, nullptr, -1, &bufferSize);
356         if (status != napi_ok) {
357             HILOG_ERROR("ConvertXml:: can not get buffer size");
358             return status;
359         }
360         buffer.reserve(bufferSize + 1);
361         buffer.resize(bufferSize);
362         if (bufferSize > 0) {
363             status = napi_get_value_string_utf8(env, napi_StrValue, buffer.data(), bufferSize + 1, &bufferSize);
364             if (status != napi_ok) {
365                 HILOG_ERROR("ConvertXml:: can not get buffer value");
366                 return status;
367             }
368         }
369         if (buffer.data() != nullptr) {
370             result = buffer;
371         }
372         return status;
373     }
374 
DealSpaces(napi_env env,const napi_value napiObj)375     void ConvertXml::DealSpaces(napi_env env, const napi_value napiObj)
376     {
377         napi_value recvTemp = nullptr;
378         napi_get_named_property(env, napiObj, "spaces", &recvTemp);
379         napi_valuetype valuetype = napi_undefined;
380         napi_typeof(env, recvTemp, &valuetype);
381         if (valuetype == napi_string) {
382             DealNapiStrValue(env, recvTemp, strSpace_);
383             spaceType_ = SpaceType::T_STRING;
384         } else if (valuetype == napi_number) {
385             int32_t iTemp;
386             if (napi_get_value_int32(env, recvTemp, &iTemp) == napi_ok) {
387                 iSpace_ = iTemp;
388                 spaceType_ = SpaceType::T_INT32;
389             }
390         }
391     }
392 
DealIgnore(napi_env env,const napi_value napiObj)393     void ConvertXml::DealIgnore(napi_env env, const napi_value napiObj)
394     {
395         std::vector<std::string> vctIgnore = {"compact", "trim", "ignoreDeclaration", "ignoreInstruction",
396                                               "ignoreAttributes", "ignoreComment", "ignoreCDATA",
397                                               "ignoreDoctype", "ignoreText"};
398         size_t vctLength = vctIgnore.size();
399         for (size_t i = 0; i < vctLength; ++i) {
400             napi_value recvTemp = nullptr;
401             bool bRecv = false;
402             napi_get_named_property(env, napiObj, vctIgnore[i].c_str(), &recvTemp);
403             if ((napi_get_value_bool(env, recvTemp, &bRecv)) == napi_ok) {
404                 switch (i) {
405                     case 0:
406                         options_.compact = bRecv;
407                         break;
408                     case 1: // 1:trim
409                         options_.trim = bRecv;
410                         break;
411                     case 2: // 2:ignoreDeclaration
412                         options_.ignoreDeclaration = bRecv;
413                         break;
414                     case 3: // 3:ignoreInstruction
415                         options_.ignoreInstruction = bRecv;
416                         break;
417                     case 4: // 4:ignoreAttributes
418                         options_.ignoreAttributes = bRecv;
419                         break;
420                     case 5: // 5:ignoreComment
421                         options_.ignoreComment = bRecv;
422                         break;
423                     case 6: // 6:ignoreCdata
424                         options_.ignoreCdata = bRecv;
425                         break;
426                     case 7: // 7:ignoreDoctype
427                         options_.ignoreDoctype = bRecv;
428                         break;
429                     case 8: // 8:ignoreText
430                         options_.ignoreText = bRecv;
431                         break;
432                     default:
433                         break;
434                 }
435             }
436         }
437     }
438 
SetDefaultKey(size_t i,const std::string strRecv)439     void ConvertXml::SetDefaultKey(size_t i, const std::string strRecv)
440     {
441         switch (i) {
442             case 0:
443                 options_.declaration = strRecv;
444                 break;
445             case 1:
446                 options_.instruction = strRecv;
447                 break;
448             case 2: // 2:attributes
449                 options_.attributes = strRecv;
450                 break;
451             case 3: // 3:text
452                 options_.text = strRecv;
453                 break;
454             case 4: // 4:cdata
455                 options_.cdata = strRecv;
456                 break;
457             case 5: // 5:doctype
458                 options_.doctype = strRecv;
459                 break;
460             case 6: // 6:comment
461                 options_.comment = strRecv;
462                 break;
463             case 7: // 7:parent
464                 options_.parent = strRecv;
465                 break;
466             case 8: // 8:type
467                 options_.type = strRecv;
468                 break;
469             case 9: // 9:name
470                 options_.name = strRecv;
471                 break;
472             case 10: // 10:elements
473                 options_.elements = strRecv;
474                 break;
475             default:
476                 break;
477         }
478     }
479 
DealOptions(napi_env env,const napi_value napiObj,bool deprecated)480     void ConvertXml::DealOptions(napi_env env, const napi_value napiObj, bool deprecated)
481     {
482         std::vector<std::string> vctOptions = {"declarationKey", "instructionKey", "attributesKey", "textKey",
483                                               "cdataKey", "doctypeKey", "commentKey", "parentKey", "typeKey",
484                                               "nameKey", "elementsKey"};
485         size_t vctLength = vctOptions.size();
486         for (size_t i = 0; i < vctLength; ++i) {
487             napi_value recvTemp = nullptr;
488             std::string strRecv = "";
489             napi_get_named_property(env, napiObj, vctOptions[i].c_str(), &recvTemp);
490             if ((DealNapiStrValue(env, recvTemp, strRecv)) == napi_ok) {
491                 SetDefaultKey(i, strRecv);
492             }
493         }
494         DealIgnore(env, napiObj);
495         if (deprecated) {
496             DealSpaces(env, napiObj);
497         }
498     }
499 
DealSingleLine(napi_env env,std::string & strXml,const napi_value & object)500     void ConvertXml::DealSingleLine(napi_env env, std::string &strXml, const napi_value &object)
501     {
502         size_t iXml = 0;
503         if ((iXml = strXml.find("xml")) != std::string::npos) {
504             xmlInfo_.bXml = true;
505             napi_value declObj = nullptr;
506             napi_create_object(env, &declObj);
507             napi_value attrObj = nullptr;
508             bool bFlag = false;
509             napi_create_object(env, &attrObj);
510             if (strXml.find("version=") != std::string::npos) {
511                 xmlInfo_.bVersion = true;
512                 SetKeyValue(env, attrObj, "version", "1.0");
513                 bFlag = true;
514             }
515             if (strXml.find("encoding=") != std::string::npos) {
516                 xmlInfo_.bEncoding = false;
517                 SetKeyValue(env, attrObj, "encoding", "utf-8");
518                 bFlag = true;
519             }
520             if (bFlag) {
521                 napi_set_named_property(env, declObj, options_.attributes.c_str(), attrObj);
522                 napi_set_named_property(env, object, options_.declaration.c_str(), declObj);
523             } else {
524                 napi_set_named_property(env, object, options_.declaration.c_str(), declObj);
525             }
526             if (strXml.find(">", iXml) == strXml.size() - 1) {
527                 strXml = "";
528             } else {
529                 strXml = strXml.substr(0, strXml.rfind("<", iXml)) + strXml.substr(strXml.find(">", iXml) + 1);
530             }
531         }
532         size_t iCount = 0;
533         size_t iLen = strXml.size();
534         for (; iCount < iLen; ++iCount) {
535             if (strXml[iCount] != ' ' && strXml[iCount] != '\v' &&
536                 strXml[iCount] != '\t' && strXml[iCount] != '\n') {
537                 break;
538             }
539         }
540         if (iCount < iLen) {
541             DealComplex(env, strXml, object);
542         }
543     }
544 
DealComplex(napi_env env,std::string & strXml,const napi_value & object) const545     void ConvertXml::DealComplex(napi_env env, std::string &strXml, const napi_value &object) const
546     {
547         if (strXml.find("<!DOCTYPE") != std::string::npos) {
548             strXml = strXml + "<node></node>";
549         } else {
550             strXml = "<node>" + strXml + "</node>";
551         }
552         xmlDocPtr doc = nullptr;
553         xmlNodePtr curNode = nullptr;
554         size_t len = strXml.size();
555         doc = xmlParseMemory(strXml.c_str(), static_cast<int>(len));
556         if (!doc) {
557             xmlFreeDoc(doc);
558         }
559         if (doc) {
560             curNode = xmlDocGetRootElement(doc);
561             curNode = curNode->children;
562             napi_value elements = nullptr;
563             napi_create_array(env, &elements);
564             bool bHasEle = false;
565             int index = 0;
566             bool bCData = false;
567             if (strXml.find("<![CDATA") != strXml.rfind("<![CDATA")) {
568                 bCData = true;
569             }
570             while (curNode != nullptr) {
571                 napi_value elementsObject = nullptr;
572                 napi_create_object(env, &elementsObject);
573                 SetNodeInfo(env, curNode, elementsObject);
574                 SetXmlElementType(env, curNode, elementsObject, bHasEle);
575                 if (!deprecated_ && curNode->type == xmlElementType::XML_TEXT_NODE &&
576                     (curNode->next != nullptr || curNode->prev != nullptr)) {
577                     curNode = curNode->next;
578                     continue;
579                 }
580                 SetEndInfo(env, curNode, elementsObject, bHasEle);
581                 napi_set_element(env, elements, index++, elementsObject);
582                 DealCDataInfo(bCData, curNode);
583             }
584             if (bHasEle) {
585                 napi_set_named_property(env, object, options_.elements.c_str(), elements);
586             }
587             xmlFreeDoc(doc);
588         }
589     }
590 
Replace(std::string & str,const std::string src,const std::string dst) const591     void ConvertXml::Replace(std::string &str, const std::string src, const std::string dst) const
592     {
593         size_t index = 0;
594         while ((index = str.find(src)) != std::string::npos) {
595             str.replace(index, src.size(), dst);
596         }
597     }
598 
DealCDataInfo(bool bCData,xmlNodePtr & curNode) const599     void ConvertXml::DealCDataInfo(bool bCData, xmlNodePtr &curNode) const
600     {
601         if (bCData && curNode->type == xmlElementType::XML_CDATA_SECTION_NODE &&
602             curNode->next && curNode->next->type == xmlElementType::XML_TEXT_NODE &&
603             curNode->next->next && curNode->next->next->type == xmlElementType::XML_CDATA_SECTION_NODE) {
604                 char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode->next));
605                 if (curContent != nullptr) {
606                     std::string strTemp = reinterpret_cast<char*>(curContent);
607                     Replace(strTemp, " ", "");
608                     Replace(strTemp, "\v", "");
609                     Replace(strTemp, "\t", "");
610                     Replace(strTemp, "\n", "");
611                     if (strTemp == "") {
612                         curNode = curNode->next->next;
613                     }
614                     xmlFree(reinterpret_cast<void*>(curContent));
615                 }
616             } else {
617                 curNode = curNode->next;
618             }
619     }
620 } // namespace OHOS::Xml
621