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