blob: 60f24b37ce4e8ce3e4a9503c3803f8a22d676a85 [file] [log] [blame]
// Copyright 2015 The Weave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/notification/xml_node.h"
#include <base/strings/stringprintf.h>
#include "src/string_utils.h"
namespace weave {
XmlNode::XmlNode(const std::string& name,
std::map<std::string, std::string> attributes)
: name_{name}, attributes_{std::move(attributes)} {}
const std::string& XmlNode::name() const {
return name_;
}
const std::string& XmlNode::text() const {
return text_;
}
const std::map<std::string, std::string>& XmlNode::attributes() const {
return attributes_;
}
const std::vector<std::unique_ptr<XmlNode>>& XmlNode::children() const {
return children_;
}
bool XmlNode::GetAttribute(const std::string& name, std::string* value) const {
auto p = attributes_.find(name);
if (p == attributes_.end())
return false;
*value = p->second;
return true;
}
std::string XmlNode::GetAttributeOrEmpty(const std::string& name) const {
std::string value;
GetAttribute(name, &value);
return value;
}
const XmlNode* XmlNode::FindFirstChild(const std::string& name_path,
bool recursive) const {
return FindChildHelper(name_path, recursive, nullptr);
}
std::vector<const XmlNode*> XmlNode::FindChildren(const std::string& name_path,
bool recursive) const {
std::vector<const XmlNode*> children;
FindChildHelper(name_path, recursive, &children);
return children;
}
const XmlNode* XmlNode::FindChildHelper(
const std::string& name_path,
bool recursive,
std::vector<const XmlNode*>* children) const {
auto parts = SplitAtFirst(name_path, "/", false);
const std::string& name = parts.first;
const std::string& rest_of_path = parts.second;
for (const auto& child : children_) {
const XmlNode* found_node = nullptr;
if (child->name() == name) {
if (rest_of_path.empty()) {
found_node = child.get();
} else {
found_node = child->FindChildHelper(rest_of_path, false, children);
}
} else if (recursive) {
found_node = child->FindChildHelper(name_path, true, children);
}
if (found_node) {
if (!children)
return found_node;
children->push_back(found_node);
}
}
return nullptr;
}
void XmlNode::SetText(const std::string& text) {
text_ = text;
}
void XmlNode::AppendText(const std::string& text) {
text_ += text;
}
void XmlNode::AddChild(std::unique_ptr<XmlNode> child) {
child->parent_ = this;
children_.push_back(std::move(child));
}
std::string XmlNode::ToString() const {
std::string xml = base::StringPrintf("<%s", name_.c_str());
for (const auto& pair : attributes_) {
base::StringAppendF(&xml, " %s=\"%s\"", pair.first.c_str(),
pair.second.c_str());
}
if (text_.empty() && children_.empty()) {
xml += "/>";
} else {
xml += '>';
if (!text_.empty()) {
xml += text_;
}
for (const auto& child : children_) {
xml += child->ToString();
}
base::StringAppendF(&xml, "</%s>", name_.c_str());
}
return xml;
}
} // namespace weave