今回は、指定された接頭辞から、それに対応する名前空間 URI を返すメソッド NamespaceContext#getNamespaceURI(String) を考えます(一覧)。
NamespaceContext#getNamespaceURI(String) の返り値
Java SE 6 の API ドキュメントを見ると、返り値は以下のように定義されています:
引数の接頭辞 | 返り値 |
---|---|
空文字列 | デフォルト名前空間 URI(デフォルト名前空間の宣言が無ければ、空文字列)が返されます。 |
xml | http://www.w3.org/XML/1998/namespace |
xmlns | http://www.w3.org/2000/xmlns/ |
null | IllegalArgumentException が投げられる |
対応する名前空間宣言がある場合 | 対応する名前空間 URI |
対応する名前空間宣言がない場合 | 空文字列 |
空文字列が引数の場合、対応する名前空間宣言がある場合、ない場合と同じ処理をすれば良さそうです。
名前空間 URI の解決手順
名前空間 URI の解決手順は以下の通り:
- 引数の接頭辞が null, "xml", "xmlns" の場合は、対応する名前空間 URI を返す(もしくは例外を投げる)
- 指定された接頭辞に対応する名前空間宣言が対象ノード上にあれば、その名前空間 URI を返す
- 親ノードがあれば、その NamespaceContext を用いて接頭辞を解決する
- 親ノードがなければ、空文字列を返す
「対応する名前空間宣言がない場合」は、「親ノードがなければ、空文字列を返す」場合に帰着します。
実装
実装は概ね次の様になります:
/** @author waman */ public abstract class AbstractNamespaceContext implements NamespaceContext{ protected abstract NamespaceContext getParentContext(); protected abstract String getNamespaceURIonCurrentNode(String prefix); public String getNamespaceURI(String prefix) { if(prefix == null) throw new IllegalArgumentException("Namespace prefix cannot be null !"); if("xml".equals(prefix)) return "http://www.w3.org/XML/1998/namespace"; if("xmlns".equals(prefix)) return "http://www.w3.org/2000/xmlns/"; String uri = getNamespaceURIonCurrentNode(prefix); // 対象ノード上に名前空間宣言がある場合 if(uri != null) return uri; NamespaceContext parent = getParentContext(); // 親ノードがある場合 if(parent != null) return parent.getNamespaceURI(prefix); // 親ノードがない場合 return NULL_NS_URI; } }