• 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 "securec.h"
18 #include "utils/log.h"
19 namespace OHOS::Xml {
ConvertXml()20     ConvertXml::ConvertXml()
21     {
22             spaceType_ = SpaceType::T_INIT;
23             strSpace_ = "";
24             iSpace_ = 0;
25     }
GetNodeType(const xmlElementType enumType) const26     std::string ConvertXml::GetNodeType(const xmlElementType enumType) const
27     {
28         std::string strResult = "";
29         switch (enumType) {
30             case xmlElementType::XML_ELEMENT_NODE:
31                 strResult = "element";
32                 break;
33             case xmlElementType::XML_ATTRIBUTE_NODE:
34                 strResult = "attribute";
35                 break;
36             case xmlElementType::XML_TEXT_NODE:
37                 strResult = "text";
38                 break;
39             case xmlElementType::XML_CDATA_SECTION_NODE:
40                 strResult = "cdata";
41                 break;
42             case xmlElementType::XML_ENTITY_REF_NODE:
43                 strResult = "entity_ref";
44                 break;
45             case xmlElementType::XML_ENTITY_NODE:
46                 strResult = "entity";
47                 break;
48             case xmlElementType::XML_PI_NODE:
49                 strResult = "instruction";
50                 break;
51             case xmlElementType::XML_COMMENT_NODE:
52                 strResult = "comment";
53                 break;
54             case xmlElementType::XML_DOCUMENT_NODE:
55                 strResult = "document";
56                 break;
57             case xmlElementType::XML_DOCUMENT_TYPE_NODE:
58                 strResult = "document_type";
59                 break;
60             case xmlElementType::XML_DOCUMENT_FRAG_NODE:
61                 strResult = "document_frag";
62                 break;
63             case xmlElementType::XML_DTD_NODE:
64                 strResult = "doctype";
65                 break;
66 #ifdef LIBXML_DOCB_ENABLED
67             case xmlElementType::XML_DOCB_DOCUMENT_NODE:
68                 strResult =  "docb_document";
69                 break;
70 #endif
71             default:
72                 break;
73         }
74         return strResult;
75     }
76 
SetKeyValue(napi_env env,const napi_value & object,const std::string strKey,const std::string strValue) const77     void ConvertXml::SetKeyValue(napi_env env, const napi_value &object, const std::string strKey,
78                                  const std::string strValue) const
79     {
80         napi_value attrValue = nullptr;
81         napi_create_string_utf8(env, strValue.c_str(), NAPI_AUTO_LENGTH, &attrValue);
82         napi_set_named_property(env, object, strKey.c_str(), attrValue);
83     }
Trim(std::string strXmltrim) const84     std::string ConvertXml::Trim(std::string strXmltrim) const
85     {
86         if (strXmltrim.empty()) {
87             return "";
88         }
89         size_t i = 0;
90         size_t strlen = strXmltrim.size();
91         for (; i < strlen;) {
92             if (strXmltrim[i] == ' ') {
93                 i++;
94             } else {
95                 break;
96             }
97         }
98         strXmltrim = strXmltrim.substr(i);
99         strlen = strXmltrim.size();
100         for (i = strlen - 1; i != 0; i--) {
101             if (strXmltrim[i] == ' ') {
102                 strXmltrim.pop_back();
103             } else {
104                 break;
105             }
106         }
107         return strXmltrim;
108     }
109 
GetPrevNodeList(napi_env env,xmlNodePtr curNode)110     void ConvertXml::GetPrevNodeList(napi_env env, xmlNodePtr curNode)
111     {
112         while (curNode->prev != nullptr) {
113             curNode = curNode->prev;
114             napi_value elementsObject = nullptr;
115             napi_create_object(env, &elementsObject);
116             char *curContent = nullptr;
117             if (curNode->type == xmlElementType::XML_PI_NODE && !options_.ignoreInstruction) {
118                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
119                 SetKeyValue(env, elementsObject, options_.name, reinterpret_cast<const char*>(curNode->name));
120                 curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
121                 if (curContent != nullptr) {
122                     SetKeyValue(env, elementsObject, options_.instruction, curContent);
123                     xmlFree(reinterpret_cast<void*>(curContent));
124                 }
125                 prevObj_.push_back(elementsObject);
126             }
127             if (curNode->type == xmlElementType::XML_COMMENT_NODE && !options_.ignoreComment) {
128                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
129                 curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
130                 if (curContent != nullptr) {
131                     SetKeyValue(env, elementsObject, options_.comment, curContent);
132                     xmlFree(reinterpret_cast<void*>(curContent));
133                 }
134                 prevObj_.push_back(elementsObject);
135             }
136             if (curNode->type == xmlElementType::XML_DTD_NODE && !options_.ignoreDoctype) {
137                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
138                 SetKeyValue(env, elementsObject, options_.doctype,
139                             reinterpret_cast<const char*>(curNode->name));
140                 prevObj_.push_back(elementsObject);
141             }
142         }
143     }
144 
SetAttributes(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject) const145     void ConvertXml::SetAttributes(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject) const
146     {
147         xmlAttr *attr = curNode->properties;
148         if (attr && !options_.ignoreAttributes) {
149             napi_value attrTitleObj = nullptr;
150             napi_create_object(env, &attrTitleObj);
151             while (attr) {
152                 SetKeyValue(env, attrTitleObj, reinterpret_cast<const char*>(attr->name),
153                             reinterpret_cast<const char*>(attr->children->content));
154                 attr = attr->next;
155             }
156             napi_set_named_property(env, elementsObject, options_.attributes.c_str(), attrTitleObj);
157         }
158     }
159 
SetXmlElementType(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject,bool & bFlag) const160     void ConvertXml::SetXmlElementType(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
161                                        bool &bFlag) const
162     {
163         char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
164         if (curNode->type == xmlElementType::XML_PI_NODE && !options_.ignoreInstruction) {
165             if (curContent != nullptr) {
166                 SetKeyValue(env, elementsObject, options_.instruction, curContent);
167                 bFlag = true;
168             }
169         } else if (curNode->type == xmlElementType::XML_COMMENT_NODE && !options_.ignoreComment) {
170             if (curContent != nullptr) {
171                 SetKeyValue(env, elementsObject, options_.comment, curContent);
172                 bFlag = true;
173             }
174         } else if (curNode->type == xmlElementType::XML_CDATA_SECTION_NODE && !options_.ignoreCdata) {
175             if (curContent != nullptr) {
176                 SetKeyValue(env, elementsObject, options_.cdata, curContent);
177                 bFlag = true;
178             }
179         }
180         if (curContent != nullptr) {
181             xmlFree(reinterpret_cast<void*>(curContent));
182         }
183     }
SetNodeInfo(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject) const184     void ConvertXml::SetNodeInfo(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject) const
185     {
186         if (curNode->type == xmlElementType::XML_TEXT_NODE) {
187             return;
188         } else {
189             if (curNode->type == xmlElementType::XML_PI_NODE) {
190                 if (!options_.ignoreInstruction) {
191                     SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
192                 }
193             } else {
194                     SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
195             }
196             if ((curNode->type != xmlElementType::XML_COMMENT_NODE) &&
197                 (curNode->type != xmlElementType::XML_CDATA_SECTION_NODE)) {
198                 if (!(curNode->type == xmlElementType::XML_PI_NODE && options_.ignoreInstruction)) {
199                     SetKeyValue(env, elementsObject, options_.name, reinterpret_cast<const char*>(curNode->name));
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)243     void ConvertXml::GetXMLInfo(napi_env env, xmlNodePtr curNode, const napi_value &object, int flag)
244     {
245         napi_value elements = nullptr;
246         napi_create_array(env, &elements);
247         napi_value recvElement = nullptr;
248         napi_create_array(env, &recvElement);
249         xmlNodePtr pNode = curNode;
250         int32_t index = 0;
251         int32_t index1 = 0;
252         bool bFlag = false;
253         while (pNode != nullptr) {
254             bFlag = false;
255             napi_value elementsObject = nullptr;
256             napi_create_object(env, &elementsObject);
257             SetNodeInfo(env, pNode, elementsObject);
258             SetAttributes(env, pNode, elementsObject);
259             napi_value tempElement = nullptr;
260             napi_create_array(env, &tempElement);
261             napi_value elementObj = nullptr;
262             napi_create_object(env, &elementObj);
263             char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(pNode));
264             if (curContent != nullptr) {
265                 if (pNode->children != nullptr) {
266                     curNode = pNode->children;
267                     GetXMLInfo(env, curNode, elementsObject, 1);
268                     bFlag = true;
269                 } else {
270                     SetXmlElementType(env, pNode, elementsObject, bFlag);
271                     SetEndInfo(env, pNode, elementsObject, bFlag);
272                 }
273                 xmlFree(reinterpret_cast<void*>(curContent));
274             }
275             SetPrevInfo(env, recvElement, flag, index1);
276             if (elementsObject != nullptr && bFlag) {
277                 napi_set_element(env, recvElement, index1++, elementsObject);
278                 elementsObject = nullptr;
279             }
280             index++;
281             pNode = pNode->next;
282         }
283         if (bFlag) {
284             napi_set_named_property(env, object, options_.elements.c_str(), recvElement);
285         }
286     }
287 
SetSpacesInfo(napi_env env,const napi_value & object) const288     void ConvertXml::SetSpacesInfo(napi_env env, const napi_value &object) const
289     {
290         napi_value iTemp = nullptr;
291         switch (spaceType_) {
292             case (SpaceType::T_INT32):
293                 napi_create_int32(env, iSpace_, &iTemp);
294                 napi_set_named_property(env, object, "spaces", iTemp);
295                 break;
296             case (SpaceType::T_STRING):
297                 SetKeyValue(env, object, "spaces", strSpace_);
298                 break;
299             case (SpaceType::T_INIT):
300                 SetKeyValue(env, object, "spaces", strSpace_);
301                 break;
302             default:
303                 break;
304             }
305     }
306 
Convert(napi_env env,std::string strXml)307     napi_value ConvertXml::Convert(napi_env env, std::string strXml)
308     {
309         xmlDocPtr doc = nullptr;
310         xmlNodePtr curNode = nullptr;
311         napi_status status = napi_ok;
312         napi_value object = nullptr;
313         status = napi_create_object(env, &object);
314         if (status != napi_ok) {
315             return nullptr;
316         }
317         Replace(strXml, "\\r", "\r");
318         Replace(strXml, "\\n", "\n");
319         Replace(strXml, "\\v", "\v");
320         Replace(strXml, "\\t", "\t");
321         Replace(strXml, "]]><![CDATA", "]]> <![CDATA");
322         size_t len = strXml.size();
323         doc = xmlParseMemory(strXml.c_str(), len);
324         if (!doc) {
325             xmlFreeDoc(doc);
326             DealSingleLine(env, strXml, object);
327             return object;
328         }
329         napi_value subObject = nullptr;
330         napi_value subSubObject = nullptr;
331         napi_create_object(env, &subSubObject);
332         napi_create_object(env, &subObject);
333         if (doc != nullptr && doc->version != nullptr) {
334             SetKeyValue(env, subSubObject, "version", (const char*)doc->version);
335         }
336         if (doc != nullptr && doc->encoding != nullptr) {
337             SetKeyValue(env, subSubObject, "encoding", (const char*)doc->encoding);
338         }
339         if (!options_.ignoreDeclaration && strXml.find("xml") != std::string::npos) {
340             napi_set_named_property(env, subObject, options_.attributes.c_str(), subSubObject);
341             napi_set_named_property(env, object, options_.declaration.c_str(), subObject);
342         }
343         if (doc != nullptr) {
344             curNode = xmlDocGetRootElement(doc);
345             GetPrevNodeList(env, curNode);
346             GetXMLInfo(env, curNode, object, 0);
347         }
348         SetSpacesInfo(env, object);
349         return object;
350     }
351 
DealNapiStrValue(napi_env env,const napi_value napi_StrValue,std::string & result) const352     napi_status ConvertXml::DealNapiStrValue(napi_env env, const napi_value napi_StrValue, std::string &result) const
353     {
354         std::string buffer = "";
355         size_t bufferSize = 0;
356         napi_status status = napi_ok;
357         status = napi_get_value_string_utf8(env, napi_StrValue, nullptr, -1, &bufferSize);
358         if (status != napi_ok) {
359             HILOG_ERROR("can not get buffer size");
360             return status;
361         }
362         buffer.reserve(bufferSize + 1);
363         buffer.resize(bufferSize);
364         if (bufferSize > 0) {
365             status = napi_get_value_string_utf8(env, napi_StrValue, buffer.data(), bufferSize + 1, &bufferSize);
366             if (status != napi_ok) {
367                 HILOG_ERROR("can not get buffer value");
368                 return status;
369             }
370         }
371         if (buffer.data() != nullptr) {
372             result = buffer;
373         }
374         return status;
375     }
376 
DealSpaces(napi_env env,const napi_value napiObj)377     void ConvertXml::DealSpaces(napi_env env, const napi_value napiObj)
378     {
379         napi_value recvTemp = nullptr;
380         napi_get_named_property(env, napiObj, "spaces", &recvTemp);
381         napi_valuetype valuetype = napi_undefined;
382         napi_typeof(env, recvTemp, &valuetype);
383         if (valuetype == napi_string) {
384             DealNapiStrValue(env, recvTemp, strSpace_);
385             spaceType_ = SpaceType::T_STRING;
386         } else if (valuetype == napi_number) {
387             int32_t iTemp;
388             if (napi_get_value_int32(env, recvTemp, &iTemp) == napi_ok) {
389                 iSpace_ = iTemp;
390                 spaceType_ = SpaceType::T_INT32;
391             }
392         }
393     }
394 
DealIgnore(napi_env env,const napi_value napiObj)395     void ConvertXml::DealIgnore(napi_env env, const napi_value napiObj)
396     {
397         std::vector<std::string> vctIgnore = {"compact", "trim", "ignoreDeclaration", "ignoreInstruction",
398                                               "ignoreAttributes", "ignoreComment", "ignoreCDATA",
399                                               "ignoreDoctype", "ignoreText"};
400         size_t vctLength = vctIgnore.size();
401         for (size_t i = 0; i < vctLength; ++i) {
402             napi_value recvTemp = nullptr;
403             bool bRecv = false;
404             napi_get_named_property(env, napiObj, vctIgnore[i].c_str(), &recvTemp);
405             if ((napi_get_value_bool(env, recvTemp, &bRecv)) == napi_ok) {
406                 switch (i) {
407                     case 0:
408                         options_.compact = bRecv;
409                         break;
410                     case 1: // 1:trim
411                         options_.trim = bRecv;
412                         break;
413                     case 2: // 2:ignoreDeclaration
414                         options_.ignoreDeclaration = bRecv;
415                         break;
416                     case 3: // 3:ignoreInstruction
417                         options_.ignoreInstruction = bRecv;
418                         break;
419                     case 4: // 4:ignoreAttributes
420                         options_.ignoreAttributes = bRecv;
421                         break;
422                     case 5: // 5:ignoreComment
423                         options_.ignoreComment = bRecv;
424                         break;
425                     case 6: // 6:ignoreCdata
426                         options_.ignoreCdata = bRecv;
427                         break;
428                     case 7: // 7:ignoreDoctype
429                         options_.ignoreDoctype = bRecv;
430                         break;
431                     case 8: // 8:ignoreText
432                         options_.ignoreText = bRecv;
433                         break;
434                     default:
435                         break;
436                 }
437             }
438         }
439     }
440 
SetDefaultKey(size_t i,const std::string strRecv)441     void ConvertXml::SetDefaultKey(size_t i, const std::string strRecv)
442     {
443         switch (i) {
444             case 0:
445                 options_.declaration = strRecv;
446                 break;
447             case 1:
448                 options_.instruction = strRecv;
449                 break;
450             case 2: // 2:attributes
451                 options_.attributes = strRecv;
452                 break;
453             case 3: // 3:text
454                 options_.text = strRecv;
455                 break;
456             case 4: // 4:cdata
457                 options_.cdata = strRecv;
458                 break;
459             case 5: // 5:doctype
460                 options_.doctype = strRecv;
461                 break;
462             case 6: // 6:comment
463                 options_.comment = strRecv;
464                 break;
465             case 7: // 7:parent
466                 options_.parent = strRecv;
467                 break;
468             case 8: // 8:type
469                 options_.type = strRecv;
470                 break;
471             case 9: // 9:name
472                 options_.name = strRecv;
473                 break;
474             case 10: // 10:elements
475                 options_.elements = strRecv;
476                 break;
477             default:
478                 break;
479         }
480     }
481 
DealOptions(napi_env env,const napi_value napiObj)482     void ConvertXml::DealOptions(napi_env env, const napi_value napiObj)
483     {
484         std::vector<std::string> vctOptions = {"declarationKey", "instructionKey", "attributesKey", "textKey",
485                                               "cdataKey", "doctypeKey", "commentKey", "parentKey", "typeKey",
486                                               "nameKey", "elementsKey"};
487         size_t vctLength = vctOptions.size();
488         for (size_t i = 0; i < vctLength; ++i) {
489             napi_value recvTemp = nullptr;
490             std::string strRecv = "";
491             napi_get_named_property(env, napiObj, vctOptions[i].c_str(), &recvTemp);
492             if ((DealNapiStrValue(env, recvTemp, strRecv)) == napi_ok) {
493                 SetDefaultKey(i, strRecv);
494             }
495         }
496         DealIgnore(env, napiObj);
497         DealSpaces(env, napiObj);
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                 SetEndInfo(env, curNode, elementsObject, bHasEle);
576                 napi_set_element(env, elements, index++, elementsObject);
577                 DealCDataInfo(bCData, curNode);
578             }
579             if (bHasEle) {
580                 napi_set_named_property(env, object, options_.elements.c_str(), elements);
581             }
582             xmlFreeDoc(doc);
583         }
584     }
585 
Replace(std::string & str,const std::string src,const std::string dst) const586     void ConvertXml::Replace(std::string &str, const std::string src, const std::string dst) const
587     {
588         size_t index = 0;
589         while ((index = str.find(src)) != std::string::npos) {
590             str.replace(index, src.size(), dst);
591         }
592     }
593 
DealCDataInfo(bool bCData,xmlNodePtr & curNode) const594     void ConvertXml::DealCDataInfo(bool bCData, xmlNodePtr &curNode) const
595     {
596         if (bCData && curNode->type == xmlElementType::XML_CDATA_SECTION_NODE &&
597             curNode->next && curNode->next->type == xmlElementType::XML_TEXT_NODE &&
598             curNode->next->next && curNode->next->next->type == xmlElementType::XML_CDATA_SECTION_NODE) {
599                 char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode->next));
600                 if (curContent != nullptr) {
601                     std::string strTemp = reinterpret_cast<char*>(curContent);
602                     Replace(strTemp, " ", "");
603                     Replace(strTemp, "\v", "");
604                     Replace(strTemp, "\t", "");
605                     Replace(strTemp, "\n", "");
606                     if (strTemp == "") {
607                         curNode = curNode->next->next;
608                     }
609                     xmlFree(reinterpret_cast<void*>(curContent));
610                 }
611             } else {
612                 curNode = curNode->next;
613             }
614     }
615 } // namespace OHOS::Xml
616