Menu

#7 xml_node comparison

Unstable (example)
open
mack
comparison (1)
5
2015-01-22
2013-10-07
No

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.

Discussion


Log in to post a comment.