1 // Copyright 2017 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "core/fxcrt/xml/cfx_xmlelement.h" 8 9 #include <utility> 10 11 #include "core/fxcrt/cfx_widetextbuf.h" 12 #include "core/fxcrt/fx_extension.h" 13 #include "core/fxcrt/xml/cfx_xmlchardata.h" 14 #include "core/fxcrt/xml/cfx_xmltext.h" 15 #include "third_party/base/ptr_util.h" 16 #include "third_party/base/stl_util.h" 17 18 CFX_XMLElement::CFX_XMLElement(const WideString& wsTag) 19 : CFX_XMLAttributeNode(wsTag) {} 20 21 CFX_XMLElement::~CFX_XMLElement() {} 22 23 FX_XMLNODETYPE CFX_XMLElement::GetType() const { 24 return FX_XMLNODE_Element; 25 } 26 27 std::unique_ptr<CFX_XMLNode> CFX_XMLElement::Clone() { 28 auto pClone = pdfium::MakeUnique<CFX_XMLElement>(GetName()); 29 pClone->SetAttributes(GetAttributes()); 30 31 WideString wsText; 32 CFX_XMLNode* pChild = m_pChild; 33 while (pChild) { 34 switch (pChild->GetType()) { 35 case FX_XMLNODE_Text: 36 wsText += static_cast<CFX_XMLText*>(pChild)->GetText(); 37 break; 38 default: 39 break; 40 } 41 pChild = pChild->m_pNext; 42 } 43 pClone->SetTextData(wsText); 44 return std::move(pClone); 45 } 46 47 WideString CFX_XMLElement::GetLocalTagName() const { 48 auto pos = GetName().Find(L':'); 49 return pos.has_value() 50 ? GetName().Right(GetName().GetLength() - pos.value() - 1) 51 : GetName(); 52 } 53 54 WideString CFX_XMLElement::GetNamespacePrefix() const { 55 auto pos = GetName().Find(L':'); 56 return pos.has_value() ? GetName().Left(pos.value()) : WideString(); 57 } 58 59 WideString CFX_XMLElement::GetNamespaceURI() const { 60 WideString wsAttri(L"xmlns"); 61 WideString wsPrefix = GetNamespacePrefix(); 62 if (wsPrefix.GetLength() > 0) { 63 wsAttri += L":"; 64 wsAttri += wsPrefix; 65 } 66 67 auto* pNode = static_cast<const CFX_XMLNode*>(this); 68 while (pNode) { 69 if (pNode->GetType() != FX_XMLNODE_Element) 70 break; 71 72 auto* pElement = static_cast<const CFX_XMLElement*>(pNode); 73 if (!pElement->HasAttribute(wsAttri)) { 74 pNode = pNode->GetNodeItem(CFX_XMLNode::Parent); 75 continue; 76 } 77 return pElement->GetString(wsAttri); 78 } 79 return WideString(); 80 } 81 82 WideString CFX_XMLElement::GetTextData() const { 83 CFX_WideTextBuf buffer; 84 CFX_XMLNode* pChild = m_pChild; 85 while (pChild) { 86 switch (pChild->GetType()) { 87 case FX_XMLNODE_Text: 88 case FX_XMLNODE_CharData: 89 buffer << static_cast<CFX_XMLText*>(pChild)->GetText(); 90 break; 91 default: 92 break; 93 } 94 pChild = pChild->m_pNext; 95 } 96 return buffer.MakeString(); 97 } 98 99 void CFX_XMLElement::SetTextData(const WideString& wsText) { 100 if (wsText.GetLength() < 1) 101 return; 102 InsertChildNode(new CFX_XMLText(wsText)); 103 } 104