Home | History | Annotate | Download | only in xml
      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