• 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,char * curContent) const156     void ConvertXml::SetXmlElementType(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
157                                        bool &bFlag, char *curContent) const
158     {
159         if (curNode->type == xmlElementType::XML_PI_NODE && !options_.ignoreInstruction) {
160             if (curContent != nullptr) {
161                 SetKeyValue(env, elementsObject, options_.instruction, curContent);
162                 bFlag = true;
163             }
164         } else if (curNode->type == xmlElementType::XML_COMMENT_NODE && !options_.ignoreComment) {
165             if (curContent != nullptr) {
166                 SetKeyValue(env, elementsObject, options_.comment, curContent);
167                 bFlag = true;
168             }
169         } else if (curNode->type == xmlElementType::XML_CDATA_SECTION_NODE && !options_.ignoreCdata) {
170             if (curContent != nullptr) {
171                 SetKeyValue(env, elementsObject, options_.cdata, curContent);
172                 bFlag = true;
173             }
174         }
175     }
176 
SetNodeInfo(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject,const std::string parentName) const177     void ConvertXml::SetNodeInfo(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
178                                  const std::string parentName) const
179     {
180         if (curNode->type == xmlElementType::XML_TEXT_NODE) {
181             return;
182         }
183         if (curNode->type == xmlElementType::XML_PI_NODE) {
184             if (!options_.ignoreInstruction) {
185                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
186             }
187         } else {
188                 SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
189         }
190         if ((curNode->type != xmlElementType::XML_COMMENT_NODE) &&
191             (curNode->type != xmlElementType::XML_CDATA_SECTION_NODE)) {
192             if (!(curNode->type == xmlElementType::XML_PI_NODE && options_.ignoreInstruction)) {
193                 SetKeyValue(env, elementsObject, options_.name, reinterpret_cast<const char*>(curNode->name));
194                 if (!parentName.empty()) {
195                     SetKeyValue(env, elementsObject, options_.parent, parentName);
196                 }
197             }
198         }
199     }
200 
SetEndInfo(napi_env env,xmlNodePtr curNode,const napi_value & elementsObject,bool & bFlag,char * curContent) const201     void ConvertXml::SetEndInfo(napi_env env, xmlNodePtr curNode, const napi_value &elementsObject,
202                                 bool &bFlag, char *curContent) const
203     {
204         SetKeyValue(env, elementsObject, options_.type, GetNodeType(curNode->type));
205         if (curNode->type == xmlElementType::XML_ELEMENT_NODE) {
206             SetKeyValue(env, elementsObject, options_.name, reinterpret_cast<const char*>(curNode->name));
207             bFlag = true;
208         } else if (curNode->type == xmlElementType::XML_TEXT_NODE) {
209             if (options_.trim) {
210                 if (curContent != nullptr) {
211                     SetKeyValue(env, elementsObject, options_.text,
212                                 Trim(curContent));
213                 }
214             } else {
215                 if (curContent != nullptr) {
216                     SetKeyValue(env, elementsObject, options_.text, curContent);
217                 }
218             }
219             if (!options_.ignoreText) {
220                 bFlag = true;
221             }
222         }
223     }
224 
SetPrevInfo(napi_env env,const napi_value & recvElement,int flag,int32_t & index1) const225     void ConvertXml::SetPrevInfo(napi_env env, const napi_value &recvElement, int flag, int32_t &index1) const
226     {
227         if (!prevObj_.empty() && !flag) {
228             for (size_t i = (prevObj_.size() - 1); i > 0; --i) {
229                 napi_set_element(env, recvElement, index1++, prevObj_[i]);
230             }
231             napi_set_element(env, recvElement, index1++, prevObj_[0]);
232         }
233     }
234 
GetXMLInfo(napi_env env,xmlNodePtr curNode,const napi_value & object,int flag,const std::string parentName)235     void ConvertXml::GetXMLInfo(napi_env env, xmlNodePtr curNode, const napi_value &object,
236                                 int flag, const std::string parentName)
237     {
238         napi_value recvElement = nullptr;
239         napi_create_array(env, &recvElement);
240         xmlNodePtr pNode = curNode;
241         int32_t index = 0;
242         bool bFlag = false;
243         while (pNode != nullptr) {
244             if (!deprecated_) {
245                 if (pNode->type == xmlElementType::XML_TEXT_NODE &&
246                     (pNode->next != nullptr || pNode->prev != nullptr)) {
247                     pNode = pNode->next;
248                     continue;
249                 }
250             }
251             bFlag = false;
252             napi_value elementsObject = nullptr;
253             napi_create_object(env, &elementsObject);
254             SetNodeInfo(env, pNode, elementsObject, parentName);
255             SetAttributes(env, pNode, elementsObject);
256             if (pNode->children != nullptr) {
257                 curNode = pNode->children;
258                 const std::string parentNameTemp = apiFlag_ ? reinterpret_cast<const char*>(pNode->name) : "";
259                 GetXMLInfo(env, curNode, elementsObject, 1, parentNameTemp);
260                 bFlag = true;
261             } else {
262                 char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(pNode));
263                 if (curContent != nullptr) {
264                     SetXmlElementType(env, pNode, elementsObject, bFlag, curContent);
265                     SetEndInfo(env, pNode, elementsObject, bFlag, curContent);
266                     xmlFree(reinterpret_cast<void*>(curContent));
267                 }
268             }
269             SetPrevInfo(env, recvElement, flag, index);
270             if (elementsObject != nullptr && bFlag) {
271                 napi_set_element(env, recvElement, index++, elementsObject);
272                 elementsObject = nullptr;
273             }
274             pNode = pNode->next;
275         }
276         if (bFlag) {
277             napi_set_named_property(env, object, options_.elements.c_str(), recvElement);
278         }
279     }
280 
SetSpacesInfo(napi_env env,const napi_value & object) const281     void ConvertXml::SetSpacesInfo(napi_env env, const napi_value &object) const
282     {
283         napi_value iTemp = nullptr;
284         switch (spaceType_) {
285             case (SpaceType::T_INT32):
286                 napi_create_int32(env, iSpace_, &iTemp);
287                 napi_set_named_property(env, object, "spaces", iTemp);
288                 break;
289             case (SpaceType::T_STRING):
290                 SetKeyValue(env, object, "spaces", strSpace_);
291                 break;
292             case (SpaceType::T_INIT):
293                 SetKeyValue(env, object, "spaces", strSpace_);
294                 break;
295             default:
296                 break;
297             }
298     }
299 
Convert(napi_env env,std::string strXml,bool deprecated)300     napi_value ConvertXml::Convert(napi_env env, std::string strXml, bool deprecated)
301     {
302         xmlNodePtr curNode = nullptr;
303         napi_value object = nullptr;
304         napi_status status = napi_create_object(env, &object);
305         if (status != napi_ok) {
306             return nullptr;
307         }
308         size_t len = strXml.size();
309         xmlDocPtr doc = xmlParseMemory(strXml.c_str(), len);
310         deprecated_ = deprecated;
311         if (!doc) {
312             xmlFreeDoc(doc);
313             DealSingleLine(env, strXml, object);
314             return object;
315         }
316         napi_value subObject = nullptr;
317         napi_value subSubObject = nullptr;
318         napi_create_object(env, &subSubObject);
319         napi_create_object(env, &subObject);
320         if (doc != nullptr && doc->version != nullptr) {
321             SetKeyValue(env, subSubObject, "version", (const char*)doc->version);
322         }
323         if (doc != nullptr && doc->encoding != nullptr) {
324             SetKeyValue(env, subSubObject, "encoding", (const char*)doc->encoding);
325         }
326         if (!options_.ignoreDeclaration && strXml.find("xml") != std::string::npos) {
327             napi_set_named_property(env, subObject, options_.attributes.c_str(), subSubObject);
328             napi_set_named_property(env, object, options_.declaration.c_str(), subObject);
329         }
330         if (doc != nullptr) {
331             curNode = xmlDocGetRootElement(doc);
332             GetPrevNodeList(env, curNode);
333             GetXMLInfo(env, curNode, object, 0);
334         }
335         xmlFreeDoc(doc);
336         if (deprecated_) {
337             SetSpacesInfo(env, object);
338         }
339         return object;
340     }
341 
DealNapiStrValue(napi_env env,const napi_value napi_StrValue,std::string & result) const342     napi_status ConvertXml::DealNapiStrValue(napi_env env, const napi_value napi_StrValue, std::string &result) const
343     {
344         std::string buffer = "";
345         size_t bufferSize = 0;
346         napi_status status = napi_ok;
347         status = napi_get_value_string_utf8(env, napi_StrValue, nullptr, -1, &bufferSize);
348         if (status != napi_ok) {
349             HILOG_ERROR("ConvertXml:: can not get buffer size");
350             return status;
351         }
352         buffer.reserve(bufferSize + 1);
353         buffer.resize(bufferSize);
354         if (bufferSize > 0) {
355             status = napi_get_value_string_utf8(env, napi_StrValue, buffer.data(), bufferSize + 1, &bufferSize);
356             if (status != napi_ok) {
357                 HILOG_ERROR("ConvertXml:: can not get buffer value");
358                 return status;
359             }
360         }
361         if (buffer.data() != nullptr) {
362             result = buffer;
363         }
364         return status;
365     }
366 
DealSpaces(napi_env env,const napi_value napiObj)367     void ConvertXml::DealSpaces(napi_env env, const napi_value napiObj)
368     {
369         napi_value recvTemp = nullptr;
370         napi_get_named_property(env, napiObj, "spaces", &recvTemp);
371         napi_valuetype valuetype = napi_undefined;
372         napi_typeof(env, recvTemp, &valuetype);
373         if (valuetype == napi_string) {
374             DealNapiStrValue(env, recvTemp, strSpace_);
375             spaceType_ = SpaceType::T_STRING;
376         } else if (valuetype == napi_number) {
377             int32_t iTemp;
378             if (napi_get_value_int32(env, recvTemp, &iTemp) == napi_ok) {
379                 iSpace_ = iTemp;
380                 spaceType_ = SpaceType::T_INT32;
381             }
382         }
383     }
384 
DealIgnore(napi_env env,const napi_value napiObj)385     void ConvertXml::DealIgnore(napi_env env, const napi_value napiObj)
386     {
387         std::vector<std::string> vctIgnore = {"compact", "trim", "ignoreDeclaration", "ignoreInstruction",
388                                               "ignoreAttributes", "ignoreComment", "ignoreCDATA",
389                                               "ignoreDoctype", "ignoreText"};
390         size_t vctLength = vctIgnore.size();
391         for (size_t i = 0; i < vctLength; ++i) {
392             napi_value recvTemp = nullptr;
393             bool bRecv = false;
394             napi_get_named_property(env, napiObj, vctIgnore[i].c_str(), &recvTemp);
395             if ((napi_get_value_bool(env, recvTemp, &bRecv)) == napi_ok) {
396                 switch (i) {
397                     case 0:
398                         options_.compact = bRecv;
399                         break;
400                     case 1: // 1:trim
401                         options_.trim = bRecv;
402                         break;
403                     case 2: // 2:ignoreDeclaration
404                         options_.ignoreDeclaration = bRecv;
405                         break;
406                     case 3: // 3:ignoreInstruction
407                         options_.ignoreInstruction = bRecv;
408                         break;
409                     case 4: // 4:ignoreAttributes
410                         options_.ignoreAttributes = bRecv;
411                         break;
412                     case 5: // 5:ignoreComment
413                         options_.ignoreComment = bRecv;
414                         break;
415                     case 6: // 6:ignoreCdata
416                         options_.ignoreCdata = bRecv;
417                         break;
418                     case 7: // 7:ignoreDoctype
419                         options_.ignoreDoctype = bRecv;
420                         break;
421                     case 8: // 8:ignoreText
422                         options_.ignoreText = bRecv;
423                         break;
424                     default:
425                         break;
426                 }
427             }
428         }
429     }
430 
SetDefaultKey(size_t i,const std::string strRecv)431     void ConvertXml::SetDefaultKey(size_t i, const std::string strRecv)
432     {
433         switch (i) {
434             case 0:
435                 options_.declaration = strRecv;
436                 break;
437             case 1:
438                 options_.instruction = strRecv;
439                 break;
440             case 2: // 2:attributes
441                 options_.attributes = strRecv;
442                 break;
443             case 3: // 3:text
444                 options_.text = strRecv;
445                 break;
446             case 4: // 4:cdata
447                 options_.cdata = strRecv;
448                 break;
449             case 5: // 5:doctype
450                 options_.doctype = strRecv;
451                 break;
452             case 6: // 6:comment
453                 options_.comment = strRecv;
454                 break;
455             case 7: // 7:parent
456                 options_.parent = strRecv;
457                 break;
458             case 8: // 8:type
459                 options_.type = strRecv;
460                 break;
461             case 9: // 9:name
462                 options_.name = strRecv;
463                 break;
464             case 10: // 10:elements
465                 options_.elements = strRecv;
466                 break;
467             default:
468                 break;
469         }
470     }
471 
DealOptions(napi_env env,const napi_value napiObj,bool deprecated)472     void ConvertXml::DealOptions(napi_env env, const napi_value napiObj, bool deprecated)
473     {
474         std::vector<std::string> vctOptions = {"declarationKey", "instructionKey", "attributesKey", "textKey",
475                                               "cdataKey", "doctypeKey", "commentKey", "parentKey", "typeKey",
476                                               "nameKey", "elementsKey"};
477         size_t vctLength = vctOptions.size();
478         for (size_t i = 0; i < vctLength; ++i) {
479             napi_value recvTemp = nullptr;
480             std::string strRecv = "";
481             napi_get_named_property(env, napiObj, vctOptions[i].c_str(), &recvTemp);
482             if ((DealNapiStrValue(env, recvTemp, strRecv)) == napi_ok) {
483                 SetDefaultKey(i, strRecv);
484             }
485         }
486         DealIgnore(env, napiObj);
487         if (deprecated) {
488             DealSpaces(env, napiObj);
489         }
490     }
491 
DealSingleLine(napi_env env,std::string & strXml,const napi_value & object)492     void ConvertXml::DealSingleLine(napi_env env, std::string &strXml, const napi_value &object)
493     {
494         size_t iXml = 0;
495         if ((iXml = strXml.find("xml")) != std::string::npos) {
496             xmlInfo_.bXml = true;
497             napi_value declObj = nullptr;
498             napi_create_object(env, &declObj);
499             napi_value attrObj = nullptr;
500             bool bFlag = false;
501             napi_create_object(env, &attrObj);
502             if (strXml.find("version=") != std::string::npos) {
503                 xmlInfo_.bVersion = true;
504                 SetKeyValue(env, attrObj, "version", "1.0");
505                 bFlag = true;
506             }
507             if (strXml.find("encoding=") != std::string::npos) {
508                 xmlInfo_.bEncoding = false;
509                 SetKeyValue(env, attrObj, "encoding", "utf-8");
510                 bFlag = true;
511             }
512             if (bFlag) {
513                 napi_set_named_property(env, declObj, options_.attributes.c_str(), attrObj);
514                 napi_set_named_property(env, object, options_.declaration.c_str(), declObj);
515             } else {
516                 napi_set_named_property(env, object, options_.declaration.c_str(), declObj);
517             }
518             if (strXml.find(">", iXml) == strXml.size() - 1) {
519                 strXml = "";
520             } else {
521                 strXml = strXml.substr(0, strXml.rfind("<", iXml)) + strXml.substr(strXml.find(">", iXml) + 1);
522             }
523         }
524         size_t iCount = 0;
525         size_t iLen = strXml.size();
526         for (; iCount < iLen; ++iCount) {
527             if (strXml[iCount] != ' ' && strXml[iCount] != '\v' &&
528                 strXml[iCount] != '\t' && strXml[iCount] != '\n') {
529                 break;
530             }
531         }
532         if (iCount < iLen) {
533             DealComplex(env, strXml, object);
534         }
535     }
536 
DealComplex(napi_env env,std::string & strXml,const napi_value & object) const537     void ConvertXml::DealComplex(napi_env env, std::string &strXml, const napi_value &object) const
538     {
539         if (strXml.find("<!DOCTYPE") != std::string::npos) {
540             strXml = strXml + "<node></node>";
541         } else {
542             strXml = "<node>" + strXml + "</node>";
543         }
544         xmlDocPtr doc = nullptr;
545         xmlNodePtr curNode = nullptr;
546         size_t len = strXml.size();
547         doc = xmlParseMemory(strXml.c_str(), static_cast<int>(len));
548         if (!doc) {
549             xmlFreeDoc(doc);
550         }
551         if (doc) {
552             curNode = xmlDocGetRootElement(doc);
553             curNode = curNode->children;
554             napi_value elements = nullptr;
555             napi_create_array(env, &elements);
556             bool bHasEle = false;
557             int index = 0;
558             bool bCData = false;
559             if (strXml.find("<![CDATA") != strXml.rfind("<![CDATA")) {
560                 bCData = true;
561             }
562             while (curNode != nullptr) {
563                 napi_value elementsObject = nullptr;
564                 napi_create_object(env, &elementsObject);
565                 SetNodeInfo(env, curNode, elementsObject);
566                 char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode));
567                 SetXmlElementType(env, curNode, elementsObject, bHasEle, curContent);
568                 if (!deprecated_ && curNode->type == xmlElementType::XML_TEXT_NODE &&
569                     (curNode->next != nullptr || curNode->prev != nullptr)) {
570                     curNode = curNode->next;
571                     continue;
572                 }
573                 SetEndInfo(env, curNode, elementsObject, bHasEle, curContent);
574                 xmlFree(curContent);
575                 napi_set_element(env, elements, index++, elementsObject);
576                 DealCDataInfo(bCData, curNode);
577             }
578             if (bHasEle) {
579                 napi_set_named_property(env, object, options_.elements.c_str(), elements);
580             }
581             xmlFreeDoc(doc);
582         }
583     }
584 
Replace(std::string & str,const std::string src,const std::string dst) const585     void ConvertXml::Replace(std::string &str, const std::string src, const std::string dst) const
586     {
587         size_t index = 0;
588         while ((index = str.find(src)) != std::string::npos) {
589             str.replace(index, src.size(), dst);
590         }
591     }
592 
DealCDataInfo(bool bCData,xmlNodePtr & curNode) const593     void ConvertXml::DealCDataInfo(bool bCData, xmlNodePtr &curNode) const
594     {
595         if (bCData && curNode->type == xmlElementType::XML_CDATA_SECTION_NODE &&
596             curNode->next && curNode->next->type == xmlElementType::XML_TEXT_NODE &&
597             curNode->next->next && curNode->next->next->type == xmlElementType::XML_CDATA_SECTION_NODE) {
598                 char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode->next));
599                 if (curContent != nullptr) {
600                     std::string strTemp = reinterpret_cast<char*>(curContent);
601                     Replace(strTemp, " ", "");
602                     Replace(strTemp, "\v", "");
603                     Replace(strTemp, "\t", "");
604                     Replace(strTemp, "\n", "");
605                     if (strTemp == "") {
606                         curNode = curNode->next->next;
607                     }
608                     xmlFree(reinterpret_cast<void*>(curContent));
609                 }
610             } else {
611                 curNode = curNode->next;
612             }
613     }
614 } // namespace OHOS::Xml
615