summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pugixml.cpp54
-rw-r--r--src/pugixml.hpp38
2 files changed, 92 insertions, 0 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index ccaec6a..06bd0ba 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -2411,6 +2411,60 @@ namespace pugi
n._root->destroy();
}
+ xml_node xml_node::find_child_by_attribute(const char* name, const char* attr_name, const char* attr_value)
+ {
+ if (empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+ if (i->name && !strcmp(name, i->name))
+ {
+ for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute)
+ if (!strcmp(attr_name, a->name) && !strcmp(attr_value, a->value))
+ return xml_node(i);
+ }
+
+ return xml_node();
+ }
+
+ xml_node xml_node::find_child_by_attribute_w(const char* name, const char* attr_name, const char* attr_value)
+ {
+ if (empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+ if (i->name && !impl::strcmpwild(name, i->name))
+ {
+ for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute)
+ if (!impl::strcmpwild(attr_name, a->name) && !impl::strcmpwild(attr_value, a->value))
+ return xml_node(i);
+ }
+
+ return xml_node();
+ }
+
+ xml_node xml_node::find_child_by_attribute(const char* attr_name, const char* attr_value)
+ {
+ if (empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+ for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute)
+ if (!strcmp(attr_name, a->name) && !strcmp(attr_value, a->value))
+ return xml_node(i);
+
+ return xml_node();
+ }
+
+ xml_node xml_node::find_child_by_attribute_w(const char* attr_name, const char* attr_value)
+ {
+ if (empty()) return xml_node();
+
+ for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+ for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute)
+ if (!impl::strcmpwild(attr_name, a->name) && !impl::strcmpwild(attr_value, a->value))
+ return xml_node(i);
+
+ return xml_node();
+ }
+
#ifndef PUGIXML_NO_STL
std::string xml_node::path(char delimiter) const
{
diff --git a/src/pugixml.hpp b/src/pugixml.hpp
index 2b014c9..3e6aa3d 100644
--- a/src/pugixml.hpp
+++ b/src/pugixml.hpp
@@ -1096,6 +1096,44 @@ namespace pugi
*/
template <typename Predicate> xml_node find_node(Predicate pred) const;
+ /**
+ * Find child node with the specified name that has specified attribute
+ *
+ * \param name - child node name
+ * \param attr_name - attribute name of child node
+ * \param attr_value - attribute value of child node
+ * \return first matching child node, or empty node
+ */
+ xml_node find_child_by_attribute(const char* name, const char* attr_name, const char* attr_value);
+
+ /**
+ * Find child node with the specified name that has specified attribute (use pattern matching for node name and attribute name/value)
+ *
+ * \param name - pattern for child node name
+ * \param attr_name - pattern for attribute name of child node
+ * \param attr_value - pattern for attribute value of child node
+ * \return first matching child node, or empty node
+ */
+ xml_node find_child_by_attribute_w(const char* name, const char* attr_name, const char* attr_value);
+
+ /**
+ * Find child node that has specified attribute
+ *
+ * \param attr_name - attribute name of child node
+ * \param attr_value - attribute value of child node
+ * \return first matching child node, or empty node
+ */
+ xml_node find_child_by_attribute(const char* attr_name, const char* attr_value);
+
+ /**
+ * Find child node that has specified attribute (use pattern matching for attribute name/value)
+ *
+ * \param attr_name - pattern for attribute name of child node
+ * \param attr_value - pattern for attribute value of child node
+ * \return first matching child node, or empty node
+ */
+ xml_node find_child_by_attribute_w(const char* attr_name, const char* attr_value);
+
#ifndef PUGIXML_NO_STL
/**
* Get the absolute node path from root as a text string.