}
}
+// Does A begin with B?
+bool begins_with(const string &a, const string &b)
+{
+ return (a.compare(0, b.size(), b) == 0);
+}
+
} // namespace
Directive::~Directive() {}
+
+string Directive::get_contents() { return ""; }
Replace::Replace(const string &str)
: str(str) {}
}
}
+string Replace::get_contents() { return str; }
+
Clone::Clone(const vector<Directive *> &subdirectives)
: subdirectives(subdirectives) {}
// Check all substitutions to see if we found anything appropriate.
for (auto it : substitution_map) {
- if (it.first == reinterpret_cast<const char *>(child->name) ||
+ string tag = reinterpret_cast<const char *>(child->name);
+
+ // Attribute substitution.
+ if (begins_with(it.first, tag + "/")) {
+ const xmlChar *attr_key = reinterpret_cast<const xmlChar *>(
+ it.first.substr(tag.size() + 1).c_str());
+ const xmlChar *attr_value = reinterpret_cast<const xmlChar *>(
+ it.second->get_contents().c_str());
+ xmlSetProp(child, attr_key, attr_value);
+ } else if ((!id.empty() && begins_with(it.first, "#" + id + "/"))) {
+ const xmlChar *attr_key = reinterpret_cast<const xmlChar *>(
+ it.first.substr(tag.size() + 2).c_str());
+ const xmlChar *attr_value = reinterpret_cast<const xmlChar *>(
+ it.second->get_contents().c_str());
+ xmlSetProp(child, attr_key, attr_value);
+ }
+
+ if (processed) {
+ continue;
+ }
+
+ // Regular substitution.
+ if (it.first == tag ||
(!id.empty() && it.first == ("#" + id))) {
it.second->process(child, clean);
processed = true;
- break;
}
}
}
public:
virtual ~Directive();
virtual void process(xmlNode *node, bool clean) = 0;
+ virtual std::string get_contents(); // Only makes sense for Replace.
};
class Replace : public Directive {
public:
Replace(const std::string &str);
virtual void process(xmlNode *node, bool clean);
+ virtual std::string get_contents();
private:
const std::string str;