Here's a start, using Guava MultiMap:
Document doc = ...;
Multimap<String, String> bindings = LinkedHashMultimap.create();
DocumentTraversal dt = (DocumentTraversal) doc;
NodeIterator i = dt.createNodeIterator(doc, NodeFilter.SHOW_ELEMENT,
null, false);
Element element = (Element) i.nextNode();
while (element != null) {
String prefix = element.getPrefix();
if (prefix != null) {
String uri = element.getNamespaceURI();
bindings.put(prefix, uri);
}
element = (Element) i.nextNode();
}
This will only pick up the bindings that are in effect, and it will not bind any default namespace (that can be fixed of course). Re-definitions of bindings will be represented in document order, but not the depth where they occurred.
I guess any further refinement of this method depends on your use case, e.g. what more information do you nedd to make something sensible of a re-defined binding?