1

Is there a way to get the prefix / namespace bindings used in a XML document preferably using standard org.w3c.org and javax.xml APIs? I understand that prefixes may by re-defined in contained elements so the API should be able to account for that as well.

I am looking for a code snipped that would take an XML document in some serialized form and return a Map<String, String> of prefix to URI name bindings (plus some extra cleverness in the API to account for redefinitions in enclosed elements). Ideally a library might be able to do fancier stuff such as identify / purge unused bindings, move duplicate bindings to their nearest common ancestor (instead of having them replicated all over the place) and so on.

Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331

1 Answers1

2

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?

forty-two
  • 12,204
  • 2
  • 26
  • 36
  • 1
    The snippet however produces the prefixes actually used ("in effect" as you say), not the ones defined and in my case I am trying to dig out a prefix defined and used as a value in a xsi:type attribute (xsi:type="a:foo") of an element - and that is not returned by the above code. – Marcus Junius Brutus Aug 22 '13 at 16:25
  • In other words, how to obtain the namespaces prefixes that are defined (as opposed to being used) ? – Marcus Junius Brutus Aug 22 '13 at 17:10
  • The proposed solution cis start, as I said. Did you create another question, or should I add to this? – forty-two Aug 22 '13 at 17:40
  • @42 it's all right. I found a way for the defined namespaces prefixes as well, I might post it as an update. – Marcus Junius Brutus Aug 22 '13 at 18:13