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 xmlFreeDoc(doc); 349 SetSpacesInfo(env, object); 350 return object; 351 } 352 DealNapiStrValue(napi_env env,const napi_value napi_StrValue,std::string & result) const353 napi_status ConvertXml::DealNapiStrValue(napi_env env, const napi_value napi_StrValue, std::string &result) const 354 { 355 std::string buffer = ""; 356 size_t bufferSize = 0; 357 napi_status status = napi_ok; 358 status = napi_get_value_string_utf8(env, napi_StrValue, nullptr, -1, &bufferSize); 359 if (status != napi_ok) { 360 HILOG_ERROR("can not get buffer size"); 361 return status; 362 } 363 buffer.reserve(bufferSize + 1); 364 buffer.resize(bufferSize); 365 if (bufferSize > 0) { 366 status = napi_get_value_string_utf8(env, napi_StrValue, buffer.data(), bufferSize + 1, &bufferSize); 367 if (status != napi_ok) { 368 HILOG_ERROR("can not get buffer value"); 369 return status; 370 } 371 } 372 if (buffer.data() != nullptr) { 373 result = buffer; 374 } 375 return status; 376 } 377 DealSpaces(napi_env env,const napi_value napiObj)378 void ConvertXml::DealSpaces(napi_env env, const napi_value napiObj) 379 { 380 napi_value recvTemp = nullptr; 381 napi_get_named_property(env, napiObj, "spaces", &recvTemp); 382 napi_valuetype valuetype = napi_undefined; 383 napi_typeof(env, recvTemp, &valuetype); 384 if (valuetype == napi_string) { 385 DealNapiStrValue(env, recvTemp, strSpace_); 386 spaceType_ = SpaceType::T_STRING; 387 } else if (valuetype == napi_number) { 388 int32_t iTemp; 389 if (napi_get_value_int32(env, recvTemp, &iTemp) == napi_ok) { 390 iSpace_ = iTemp; 391 spaceType_ = SpaceType::T_INT32; 392 } 393 } 394 } 395 DealIgnore(napi_env env,const napi_value napiObj)396 void ConvertXml::DealIgnore(napi_env env, const napi_value napiObj) 397 { 398 std::vector<std::string> vctIgnore = {"compact", "trim", "ignoreDeclaration", "ignoreInstruction", 399 "ignoreAttributes", "ignoreComment", "ignoreCDATA", 400 "ignoreDoctype", "ignoreText"}; 401 size_t vctLength = vctIgnore.size(); 402 for (size_t i = 0; i < vctLength; ++i) { 403 napi_value recvTemp = nullptr; 404 bool bRecv = false; 405 napi_get_named_property(env, napiObj, vctIgnore[i].c_str(), &recvTemp); 406 if ((napi_get_value_bool(env, recvTemp, &bRecv)) == napi_ok) { 407 switch (i) { 408 case 0: 409 options_.compact = bRecv; 410 break; 411 case 1: // 1:trim 412 options_.trim = bRecv; 413 break; 414 case 2: // 2:ignoreDeclaration 415 options_.ignoreDeclaration = bRecv; 416 break; 417 case 3: // 3:ignoreInstruction 418 options_.ignoreInstruction = bRecv; 419 break; 420 case 4: // 4:ignoreAttributes 421 options_.ignoreAttributes = bRecv; 422 break; 423 case 5: // 5:ignoreComment 424 options_.ignoreComment = bRecv; 425 break; 426 case 6: // 6:ignoreCdata 427 options_.ignoreCdata = bRecv; 428 break; 429 case 7: // 7:ignoreDoctype 430 options_.ignoreDoctype = bRecv; 431 break; 432 case 8: // 8:ignoreText 433 options_.ignoreText = bRecv; 434 break; 435 default: 436 break; 437 } 438 } 439 } 440 } 441 SetDefaultKey(size_t i,const std::string strRecv)442 void ConvertXml::SetDefaultKey(size_t i, const std::string strRecv) 443 { 444 switch (i) { 445 case 0: 446 options_.declaration = strRecv; 447 break; 448 case 1: 449 options_.instruction = strRecv; 450 break; 451 case 2: // 2:attributes 452 options_.attributes = strRecv; 453 break; 454 case 3: // 3:text 455 options_.text = strRecv; 456 break; 457 case 4: // 4:cdata 458 options_.cdata = strRecv; 459 break; 460 case 5: // 5:doctype 461 options_.doctype = strRecv; 462 break; 463 case 6: // 6:comment 464 options_.comment = strRecv; 465 break; 466 case 7: // 7:parent 467 options_.parent = strRecv; 468 break; 469 case 8: // 8:type 470 options_.type = strRecv; 471 break; 472 case 9: // 9:name 473 options_.name = strRecv; 474 break; 475 case 10: // 10:elements 476 options_.elements = strRecv; 477 break; 478 default: 479 break; 480 } 481 } 482 DealOptions(napi_env env,const napi_value napiObj)483 void ConvertXml::DealOptions(napi_env env, const napi_value napiObj) 484 { 485 std::vector<std::string> vctOptions = {"declarationKey", "instructionKey", "attributesKey", "textKey", 486 "cdataKey", "doctypeKey", "commentKey", "parentKey", "typeKey", 487 "nameKey", "elementsKey"}; 488 size_t vctLength = vctOptions.size(); 489 for (size_t i = 0; i < vctLength; ++i) { 490 napi_value recvTemp = nullptr; 491 std::string strRecv = ""; 492 napi_get_named_property(env, napiObj, vctOptions[i].c_str(), &recvTemp); 493 if ((DealNapiStrValue(env, recvTemp, strRecv)) == napi_ok) { 494 SetDefaultKey(i, strRecv); 495 } 496 } 497 DealIgnore(env, napiObj); 498 DealSpaces(env, napiObj); 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 SetEndInfo(env, curNode, elementsObject, bHasEle); 577 napi_set_element(env, elements, index++, elementsObject); 578 DealCDataInfo(bCData, curNode); 579 } 580 if (bHasEle) { 581 napi_set_named_property(env, object, options_.elements.c_str(), elements); 582 } 583 xmlFreeDoc(doc); 584 } 585 } 586 Replace(std::string & str,const std::string src,const std::string dst) const587 void ConvertXml::Replace(std::string &str, const std::string src, const std::string dst) const 588 { 589 size_t begCdata = 0; 590 size_t endCdata = 0; 591 size_t pos = 0; 592 size_t flag = 0; 593 size_t count = 0; 594 std::string temp = ""; 595 while ((begCdata = str.find("<![CDATA", endCdata - count)) != std::string::npos && 596 (endCdata = str.find("]]>", begCdata)) != std::string::npos) { 597 size_t strLen = begCdata - flag; 598 temp = str.substr(flag, strLen); 599 count = 0; 600 while ((pos = temp.find(src)) != std::string::npos) { 601 temp.replace(pos, src.size(), dst); 602 count++; 603 } 604 str.replace(flag, strLen, temp); 605 flag = endCdata - count + 3; // 3 : length of "]]>" 606 } 607 temp = str.substr(flag); 608 while ((pos = temp.find(src)) != std::string::npos) { 609 temp.replace(pos, src.size(), dst); 610 } 611 str.replace(flag, str.size() - flag, temp); 612 } 613 DealCDataInfo(bool bCData,xmlNodePtr & curNode) const614 void ConvertXml::DealCDataInfo(bool bCData, xmlNodePtr &curNode) const 615 { 616 if (bCData && curNode->type == xmlElementType::XML_CDATA_SECTION_NODE && 617 curNode->next && curNode->next->type == xmlElementType::XML_TEXT_NODE && 618 curNode->next->next && curNode->next->next->type == xmlElementType::XML_CDATA_SECTION_NODE) { 619 char *curContent = reinterpret_cast<char*>(xmlNodeGetContent(curNode->next)); 620 if (curContent != nullptr) { 621 std::string strTemp = reinterpret_cast<char*>(curContent); 622 Replace(strTemp, " ", ""); 623 Replace(strTemp, "\v", ""); 624 Replace(strTemp, "\t", ""); 625 Replace(strTemp, "\n", ""); 626 if (strTemp == "") { 627 curNode = curNode->next->next; 628 } 629 xmlFree(reinterpret_cast<void*>(curContent)); 630 } 631 } else { 632 curNode = curNode->next; 633 } 634 } 635 } // namespace OHOS::Xml 636