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