In case people find this question and need something that is implemented for Node.js or a browser, I provide an example of the link and code for the implementation that I wrote, which you can find on github here: ( https: // github.com/hoonto/jqgram.git ) based on existing PyGram Python code ( https://github.com/Sycondaman/PyGram ).
This is an algorithm for approximating distance to a tree, but it is much faster than finding the true editing distance. The approximation is performed in O (n log n) time and O (n) space, while the true editing distance is often O (n ^ 3) or O (n ^ 2) using well-known algorithms for the true editing distance. See the Academic article that follows the PQ-Gram algorithm: ( http://www.vldb2005.org/program/paper/wed/p301-augsten.pdf )
So using jqgram:
Example:
var jq = require("jqgram").jqgram; var root1 = { "thelabel": "a", "thekids": [ { "thelabel": "b", "thekids": [ { "thelabel": "c" }, { "thelabel": "d" } ]}, { "thelabel": "e" }, { "thelabel": "f" } ] } var root2 = { "name": "a", "kiddos": [ { "name": "b", "kiddos": [ { "name": "c" }, { "name": "d" }, { "name": "y" } ]}, { "name": "e" }, { "name": "x" } ] } jq.distance({ root: root1, lfn: function(node){ return node.thelabel; }, cfn: function(node){ return node.thekids; } },{ root: root2, lfn: function(node){ return node.name; }, cfn: function(node){ return node.kiddos; } },{ p:2, q:3 }, function(result) { console.log(result.distance); });
And this gives you a number from 0 to 1. The closer to zero, the more closely the two trees are connected in jqgram. One approach might be to use jqgram to narrow on several closely related trees from many trees based on its speed, and then use the true editing distance on the few remaining trees that you need to study more carefully, and for this you can find a python implementation for a link or port algorithm of Zhang and Shashi, for example.
Please note that the lfn and cfn parameters determine how each tree should determine the label names of the node and the child array for each root of the tree independently, so that you can do funny things, for example, comparing an object with the browser DOM. All you have to do is provide these functions along with each root, and jqgram will do the rest by calling your provided lfn and cfn functions to create the trees. So in this sense, it (in my opinion, one way or another) is much easier to use than PyGram. Also its javascript, so use its client or server!
ALSO, to answer the question about loop detection, check the clone method inside jqgram, there is loop detection there, but the credit for this belongs to the node-clone author, from which this part has been slightly modified and included.