xml_node comparison
Brought to you by:
kaalus
I use RapidXml to compare two XML documents, comparing the structure. I wrote a comparison function for xml_node:
namespace rapidxml {
template<typename Ch>
Bool operator==(const xml_node<Ch>& lhs, const xml_node<Ch>& rhs);
template<typename Ch>
Bool operator!=(const xml_node<Ch>& lhs, const xml_node<Ch>& rhs) {
return !(lhs == rhs);
}
template<typename Ch>
Bool operator==(const xml_node<Ch>& lhs, const xml_node<Ch>& rhs) {
// Check current nodes are the same
if ((lhs.type() != rhs.type()) ||
(0 != std::strncmp(lhs.name(), rhs.name(), lhs.name_size())) ||
(0 != std::strncmp(lhs.value(), rhs.value(), lhs.value_size()))) {
return false;
}
// Check the node attributes are the same
const xml_attribute<Ch> * lattr = lhs.first_attribute();
const xml_attribute<Ch> * rattr = rhs.first_attribute();
while (lattr || rattr) {
if (!lattr || !rattr) {
return false;
}
if ((0 != std::strncmp(lattr->name(), rattr->name(), lattr->name_size())) ||
(0 != std::strncmp(lattr->value(), rattr->value(), lattr->value_size()))) {
return false;
}
lattr = lattr->next_attribute();
rattr = rattr->next_attribute();
}
// Recurse into the children
const xml_node<Ch> * lchild = lhs.first_node();
const xml_node<Ch> * rchild = rhs.first_node();
if (((lchild == NULL) && (rchild != NULL)) ||
((lchild != NULL) && (rchild == NULL))) {
return false;
} else if ((lchild == NULL) && (rchild == NULL)) {
return true;
} else {
while (lchild) {
if (*lchild != *rchild) {
return false;
}
lchild = lchild->next_sibling();
if (lchild == NULL) {
break;
}
if (rchild->next_sibling(lchild->name())) {
rchild = rchild->next_sibling(lchild->name());
} else if (rchild->previous_sibling(lchild->name())) {
rchild = rchild->previous_sibling(lchild->name());
} else {
return false;
}
}
}
return true;
}
} // namespace rapidxml
It would be great if there was a rapidxml_comparison.hpp that provided the comparison functions. If this is something that the project would like to include I would happily improve this function with doxygen, etc.