All-You-Can-Gulp Steamin' Hot Hard-Core Java! No-compromise, professional, non-newbie tips, tricks and solutions. You're invited to join!

Thursday, May 22, 2003

Utility Function of the Day

There hasn't been a utility function of the day for a long time around here, so this one is extra special.
The following method calculates a digest for a DOM hierarchy including attribute values and text content. The special part about it is that it ignores ordering of elements and attributes and disregards comments completely.

The Code:
/**

* Recursively calculate DOM digest,
* disregarding order but taking all content except
* comments into consideration.
* @param node The node to start with
*/
public static long digestDOM(Node node)
{
long digest = 0L;

/**
* First calculate the 'self' digest
*/
if (node instanceof Attr)
{
Attr attr = (Attr) node;

digest = attr.getName().hashCode() + attr.getValue().hashCode();
}
else if (node instanceof Text)
{
Text text = (Text) node;

digest = XMLUtils.getContent(text).hashCode();
}
else if (node instanceof Element)
{
Element element = (Element) node;

digest = element.getTagName().hashCode();
}

/**
* Now calculate the attribute's digest, disregarding order
*/
long attributeDigest = 0L;

NamedNodeMap attributes = node.getAttributes();

if (attributes != null)
{
/**
* Iterate through a node list, examine only elements
*/
int attributeCount = attributes.getLength();

for (int i = 0; i < attributeCount; i++)
{
Node currentNode = attributes.item(i);

attributeDigest += digestDOM(currentNode);
}
}

/**
* Append the attribute digest
*/
digest = (digest * 2 + (attributeDigest));

/**
* Then calculate the children, disregarding ordering
*/
long childrenDigest = 0L;

/**
* Iterate through a node list, examine only elements
*/

NodeList childNodes = node.getChildNodes();

int nodeCount = childNodes.getLength();

for (int i = 0; i < nodeCount; i++)
{
Node currentNode = childNodes.item(i);

childrenDigest += digestDOM(currentNode);
}

/**
* Append the children digest
*/
digest = (digest * 4 + (childrenDigest));

return digest;
}


----
Enjoy!