+package org.wamblee.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import sun.security.krb5.internal.ktab.l;
+
+/**
+ * Utility class for performing various operations on DOM trees.
+ */
+public final class DOMUtility {
+
+ /**
+ * Disabled constructor.
+ *
+ */
+ private DOMUtility() {
+ // Empty
+ }
+
+ /**
+ * Removes duplicate attributes from a DOM tree.
+ * @param aNode Node to remove duplicate attributes from (recursively).
+ * Attributes of the node itself are not dealt with. Only the child
+ * nodes are dealt with.
+ */
+ public static void removeDuplicateAttributes(Node aNode) {
+ NodeList list = aNode.getChildNodes();
+ for (int i = 0; i < list.getLength(); i++) {
+ Node node = list.item(i);
+ if ( node instanceof Element ) {
+ removeDuplicateAttributes((Element)node);
+ removeDuplicateAttributes(node);
+ }
+ }
+ }
+
+ /**
+ * Removes duplicate attributes from an element.
+ * @param aElement Element.
+ */
+ private static void removeDuplicateAttributes(Element aElement) {
+ NamedNodeMap attributes = aElement.getAttributes();
+ Map<String, Attr> uniqueAttributes = new TreeMap<String, Attr>();
+ List<Attr> attlist = new ArrayList<Attr>();
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Attr attribute = (Attr)attributes.item(i);
+ if ( uniqueAttributes.containsKey(attribute.getNodeName())) {
+ System.out.println("Detected duplicate attribute '" + attribute.getNodeName() + "'");
+ }
+ uniqueAttributes.put(attribute.getNodeName(), attribute);
+ attlist.add(attribute);
+ }
+ // Remove all attributes from the element.
+ for (Attr att: attlist) {
+ aElement.removeAttributeNode(att);
+ }
+ // Add the unique attributes back to the element.
+ for (Attr att: uniqueAttributes.values()) {
+ aElement.setAttributeNode(att);
+ }
+ }
+}