Vitaly Buka | 4615e0d | 2015-10-14 15:35:12 -0700 | [diff] [blame] | 1 | // Copyright 2015 The Weave Authors. All rights reserved. |
Alex Vakulenko | bf71f70 | 2015-05-18 14:30:56 -0700 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Stefan Sauer | 2d16dfa | 2015-09-25 17:08:35 +0200 | [diff] [blame] | 5 | #include "src/notification/xml_node.h" |
Alex Vakulenko | bf71f70 | 2015-05-18 14:30:56 -0700 | [diff] [blame] | 6 | |
| 7 | #include <base/strings/stringprintf.h> |
Vitaly Buka | 24d6fd5 | 2015-08-13 23:22:48 -0700 | [diff] [blame] | 8 | |
Stefan Sauer | 2d16dfa | 2015-09-25 17:08:35 +0200 | [diff] [blame] | 9 | #include "src/string_utils.h" |
Alex Vakulenko | bf71f70 | 2015-05-18 14:30:56 -0700 | [diff] [blame] | 10 | |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 11 | namespace weave { |
Alex Vakulenko | bf71f70 | 2015-05-18 14:30:56 -0700 | [diff] [blame] | 12 | |
| 13 | XmlNode::XmlNode(const std::string& name, |
| 14 | std::map<std::string, std::string> attributes) |
Vitaly Buka | 4ebd329 | 2015-09-23 18:04:17 -0700 | [diff] [blame] | 15 | : name_{name}, attributes_{std::move(attributes)} {} |
Alex Vakulenko | bf71f70 | 2015-05-18 14:30:56 -0700 | [diff] [blame] | 16 | |
| 17 | const std::string& XmlNode::name() const { |
| 18 | return name_; |
| 19 | } |
| 20 | |
| 21 | const std::string& XmlNode::text() const { |
| 22 | return text_; |
| 23 | } |
| 24 | |
| 25 | const std::map<std::string, std::string>& XmlNode::attributes() const { |
| 26 | return attributes_; |
| 27 | } |
| 28 | |
| 29 | const std::vector<std::unique_ptr<XmlNode>>& XmlNode::children() const { |
| 30 | return children_; |
| 31 | } |
| 32 | |
| 33 | bool XmlNode::GetAttribute(const std::string& name, std::string* value) const { |
| 34 | auto p = attributes_.find(name); |
| 35 | if (p == attributes_.end()) |
| 36 | return false; |
| 37 | |
| 38 | *value = p->second; |
| 39 | return true; |
| 40 | } |
| 41 | |
| 42 | std::string XmlNode::GetAttributeOrEmpty(const std::string& name) const { |
| 43 | std::string value; |
| 44 | GetAttribute(name, &value); |
| 45 | return value; |
| 46 | } |
| 47 | |
| 48 | const XmlNode* XmlNode::FindFirstChild(const std::string& name_path, |
| 49 | bool recursive) const { |
| 50 | return FindChildHelper(name_path, recursive, nullptr); |
| 51 | } |
| 52 | |
| 53 | std::vector<const XmlNode*> XmlNode::FindChildren(const std::string& name_path, |
| 54 | bool recursive) const { |
| 55 | std::vector<const XmlNode*> children; |
| 56 | FindChildHelper(name_path, recursive, &children); |
| 57 | return children; |
| 58 | } |
| 59 | |
| 60 | const XmlNode* XmlNode::FindChildHelper( |
| 61 | const std::string& name_path, |
| 62 | bool recursive, |
| 63 | std::vector<const XmlNode*>* children) const { |
Vitaly Buka | 24d6fd5 | 2015-08-13 23:22:48 -0700 | [diff] [blame] | 64 | auto parts = SplitAtFirst(name_path, "/", false); |
| 65 | const std::string& name = parts.first; |
| 66 | const std::string& rest_of_path = parts.second; |
Alex Vakulenko | bf71f70 | 2015-05-18 14:30:56 -0700 | [diff] [blame] | 67 | for (const auto& child : children_) { |
| 68 | const XmlNode* found_node = nullptr; |
| 69 | if (child->name() == name) { |
| 70 | if (rest_of_path.empty()) { |
| 71 | found_node = child.get(); |
| 72 | } else { |
| 73 | found_node = child->FindChildHelper(rest_of_path, false, children); |
| 74 | } |
| 75 | } else if (recursive) { |
| 76 | found_node = child->FindChildHelper(name_path, true, children); |
| 77 | } |
| 78 | |
| 79 | if (found_node) { |
| 80 | if (!children) |
| 81 | return found_node; |
| 82 | children->push_back(found_node); |
| 83 | } |
| 84 | } |
| 85 | return nullptr; |
| 86 | } |
| 87 | |
| 88 | void XmlNode::SetText(const std::string& text) { |
| 89 | text_ = text; |
| 90 | } |
| 91 | |
| 92 | void XmlNode::AppendText(const std::string& text) { |
| 93 | text_ += text; |
| 94 | } |
| 95 | |
| 96 | void XmlNode::AddChild(std::unique_ptr<XmlNode> child) { |
| 97 | child->parent_ = this; |
| 98 | children_.push_back(std::move(child)); |
| 99 | } |
| 100 | |
| 101 | std::string XmlNode::ToString() const { |
| 102 | std::string xml = base::StringPrintf("<%s", name_.c_str()); |
| 103 | for (const auto& pair : attributes_) { |
| 104 | base::StringAppendF(&xml, " %s=\"%s\"", pair.first.c_str(), |
| 105 | pair.second.c_str()); |
| 106 | } |
| 107 | if (text_.empty() && children_.empty()) { |
| 108 | xml += "/>"; |
| 109 | } else { |
| 110 | xml += '>'; |
| 111 | if (!text_.empty()) { |
| 112 | xml += text_; |
| 113 | } |
| 114 | for (const auto& child : children_) { |
| 115 | xml += child->ToString(); |
| 116 | } |
| 117 | base::StringAppendF(&xml, "</%s>", name_.c_str()); |
| 118 | } |
| 119 | return xml; |
| 120 | } |
| 121 | |
Vitaly Buka | b6f015a | 2015-07-09 14:59:23 -0700 | [diff] [blame] | 122 | } // namespace weave |