// Copyright 2017 PDFium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com #include "core/fxcrt/xml/cfx_xmlelement.h" #include #include "core/fxcrt/cfx_widetextbuf.h" #include "core/fxcrt/fx_extension.h" #include "core/fxcrt/xml/cfx_xmlchardata.h" #include "core/fxcrt/xml/cfx_xmltext.h" #include "third_party/base/ptr_util.h" #include "third_party/base/stl_util.h" CFX_XMLElement::CFX_XMLElement(const CFX_WideString& wsTag) : CFX_XMLAttributeNode(wsTag) {} CFX_XMLElement::~CFX_XMLElement() {} FX_XMLNODETYPE CFX_XMLElement::GetType() const { return FX_XMLNODE_Element; } std::unique_ptr CFX_XMLElement::Clone() { auto pClone = pdfium::MakeUnique(GetName()); pClone->SetAttributes(GetAttributes()); CFX_WideString wsText; CFX_XMLNode* pChild = m_pChild; while (pChild) { switch (pChild->GetType()) { case FX_XMLNODE_Text: wsText += static_cast(pChild)->GetText(); break; default: break; } pChild = pChild->m_pNext; } pClone->SetTextData(wsText); return std::move(pClone); } CFX_WideString CFX_XMLElement::GetLocalTagName() const { auto pos = GetName().Find(L':'); return pos.has_value() ? GetName().Right(GetName().GetLength() - pos.value() - 1) : GetName(); } CFX_WideString CFX_XMLElement::GetNamespacePrefix() const { auto pos = GetName().Find(L':'); return pos.has_value() ? GetName().Left(pos.value()) : CFX_WideString(); } CFX_WideString CFX_XMLElement::GetNamespaceURI() const { CFX_WideString wsAttri(L"xmlns"); CFX_WideString wsPrefix = GetNamespacePrefix(); if (wsPrefix.GetLength() > 0) { wsAttri += L":"; wsAttri += wsPrefix; } auto* pNode = static_cast(this); while (pNode) { if (pNode->GetType() != FX_XMLNODE_Element) break; auto* pElement = static_cast(pNode); if (!pElement->HasAttribute(wsAttri)) { pNode = pNode->GetNodeItem(CFX_XMLNode::Parent); continue; } return pElement->GetString(wsAttri); } return CFX_WideString(); } CFX_WideString CFX_XMLElement::GetTextData() const { CFX_WideTextBuf buffer; CFX_XMLNode* pChild = m_pChild; while (pChild) { switch (pChild->GetType()) { case FX_XMLNODE_Text: case FX_XMLNODE_CharData: buffer << static_cast(pChild)->GetText(); break; default: break; } pChild = pChild->m_pNext; } return buffer.MakeString(); } void CFX_XMLElement::SetTextData(const CFX_WideString& wsText) { if (wsText.GetLength() < 1) return; InsertChildNode(new CFX_XMLText(wsText)); }