Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cfx_xmlelement.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
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 "core/fxcrt/fx_extension.h"
10#include "core/fxcrt/xml/cfx_xmlchardata.h"
11#include "core/fxcrt/xml/cfx_xmldocument.h"
12#include "core/fxcrt/xml/cfx_xmltext.h"
13#include "third_party/base/check.h"
14
15CFX_XMLElement::CFX_XMLElement(const WideString& wsTag) : name_(wsTag) {
16 DCHECK(!name_.IsEmpty());
17}
18
19CFX_XMLElement::~CFX_XMLElement() = default;
20
21CFX_XMLNode::Type CFX_XMLElement::GetType() const {
22 return Type::kElement;
23}
24
25CFX_XMLNode* CFX_XMLElement::Clone(CFX_XMLDocument* doc) {
26 auto* node = doc->CreateNode<CFX_XMLElement>(name_);
27 node->attrs_ = attrs_;
28
29 // TODO(dsinclair): This clone is wrong. It doesn't clone all child nodes just
30 // text nodes?
31 for (CFX_XMLNode* pChild = GetFirstChild(); pChild;
32 pChild = pChild->GetNextSibling()) {
33 if (pChild->GetType() == Type::kText)
34 node->AppendLastChild(pChild->Clone(doc));
35 }
36 return node;
37}
38
39WideString CFX_XMLElement::GetLocalTagName() const {
40 auto pos = name_.Find(L':');
41 return pos.has_value() ? name_.Last(name_.GetLength() - pos.value() - 1)
42 : name_;
43}
44
45WideString CFX_XMLElement::GetNamespacePrefix() const {
46 auto pos = name_.Find(L':');
47 return pos.has_value() ? name_.First(pos.value()) : WideString();
48}
49
50WideString CFX_XMLElement::GetNamespaceURI() const {
51 WideString attr(L"xmlns");
52 WideString wsPrefix = GetNamespacePrefix();
53 if (!wsPrefix.IsEmpty()) {
54 attr += L":";
55 attr += wsPrefix;
56 }
57 const CFX_XMLNode* pNode = this;
58 while (pNode && pNode->GetType() == Type::kElement) {
59 auto* pElement = static_cast<const CFX_XMLElement*>(pNode);
60 if (!pElement->HasAttribute(attr)) {
61 pNode = pNode->GetParent();
62 continue;
63 }
64 return pElement->GetAttribute(attr);
65 }
66 return WideString();
67}
68
69WideString CFX_XMLElement::GetTextData() const {
70 WideString buffer;
71 for (CFX_XMLNode* pChild = GetFirstChild(); pChild;
72 pChild = pChild->GetNextSibling()) {
73 CFX_XMLText* pText = ToXMLText(pChild);
74 if (pText)
75 buffer += pText->GetText();
76 }
77 return buffer;
78}
79
80void CFX_XMLElement::Save(
81 const RetainPtr<IFX_RetainableWriteStream>& pXMLStream) {
82 ByteString bsNameEncoded = name_.ToUTF8();
83
84 pXMLStream->WriteString("<");
85 pXMLStream->WriteString(bsNameEncoded.AsStringView());
86
87 for (const auto& it : attrs_) {
88 // Note, the space between attributes is added by AttributeToString which
89 // writes a blank as the first character.
90 pXMLStream->WriteString(
91 AttributeToString(it.first, it.second).ToUTF8().AsStringView());
92 }
93
94 if (!GetFirstChild()) {
95 pXMLStream->WriteString(" />\n");
96 return;
97 }
98
99 pXMLStream->WriteString(">\n");
100
101 for (CFX_XMLNode* pChild = GetFirstChild(); pChild;
102 pChild = pChild->GetNextSibling()) {
103 pChild->Save(pXMLStream);
104 }
105 pXMLStream->WriteString("</");
106 pXMLStream->WriteString(bsNameEncoded.AsStringView());
107 pXMLStream->WriteString(">\n");
108}
109
110CFX_XMLElement* CFX_XMLElement::GetFirstChildNamed(WideStringView name) const {
111 return GetNthChildNamed(name, 0);
112}
113
114CFX_XMLElement* CFX_XMLElement::GetNthChildNamed(WideStringView name,
115 size_t idx) const {
116 for (auto* child = GetFirstChild(); child; child = child->GetNextSibling()) {
117 CFX_XMLElement* elem = ToXMLElement(child);
118 if (!elem || elem->name_ != name)
119 continue;
120 if (idx == 0)
121 return elem;
122
123 --idx;
124 }
125 return nullptr;
126}
127
128bool CFX_XMLElement::HasAttribute(const WideString& name) const {
129 return attrs_.find(name) != attrs_.end();
130}
131
132WideString CFX_XMLElement::GetAttribute(const WideString& name) const {
133 auto it = attrs_.find(name);
134 return it != attrs_.end() ? it->second : WideString();
135}
136
137void CFX_XMLElement::SetAttribute(const WideString& name,
138 const WideString& value) {
139 attrs_[name] = value;
140}
141
142void CFX_XMLElement::RemoveAttribute(const WideString& name) {
143 attrs_.erase(name);
144}
145
146WideString CFX_XMLElement::AttributeToString(const WideString& name,
147 const WideString& value) {
148 WideString ret = L" ";
149 ret += name;
150 ret += L"=\"";
151 ret += value.EncodeEntities();
152 ret += L"\"";
153 return ret;
154}
CFX_XMLText * ToXMLText(CFX_XMLNode *pNode)
Definition cfx_xmltext.h:38
void Save(const RetainPtr< IFX_RetainableWriteStream > &pXMLStream) override
WideString GetNamespacePrefix() const
WideString GetTextData() const
CFX_XMLNode * Clone(CFX_XMLDocument *doc) override
~CFX_XMLElement() override
CFX_XMLElement(const WideString &wsTag)
bool HasAttribute(const WideString &name) const
WideString GetLocalTagName() const
Type GetType() const override
WideString GetAttribute(const WideString &name) const
WideString GetNamespaceURI() const
void SetAttribute(const WideString &name, const WideString &value)
CFX_XMLElement * GetFirstChildNamed(WideStringView name) const
void RemoveAttribute(const WideString &name)
CFX_XMLElement * GetNthChildNamed(WideStringView name, size_t idx) const
virtual void Save(const RetainPtr< IFX_RetainableWriteStream > &pXMLStream)=0
virtual CFX_XMLNode * Clone(CFX_XMLDocument *doc)=0
virtual Type GetType() const =0
const WideString & GetText() const
Definition cfx_xmltext.h:25
WideString & operator+=(const WideString &str)
WideString & operator+=(const wchar_t *str)
bool IsEmpty() const
Definition widestring.h:118
WideString(const wchar_t *ptr)
WideString EncodeEntities() const