AbstractCompositeNamespaceContext は、親となる NamespaceContext(例えば親ノードの NamespaceContext)を持ち、それに加えて追加の名前空間宣言があるような場合に使用する NamespaceContext です。 これは以前の記事での AbstractNamespaceContext に対応するものです(一覧)。
親となる NamespaceContext を取得するメソッド
まず、親となる NamespaceContext(例えば親ノードの NamespaceContext)を取得する抽象メソッドを定義しておきましょう:
protected abstract NamespaceContext getParentContext();
以前は、「親がない場合は null を返す」としてましたが、これを変更して、「親がない場合は EmptyNamespaceContext.INSTANCE を返す」とします。
getNamespaceURISimply(String) メソッドの実装
次に AbstractNamespaceContext クラスに定義された抽象メソッド getNamespaceURI(String) メソッドの実装を考えます。 このために、まず新に次の抽象メソッドを定義します:
protected abstract String getNamespaceURILocally(String prefix);
これは以前の記事で「getNamespaceURIonCurrentNode(String)」としていたもので(6文字も短くなりました(笑))、親ノードを使わずに接頭辞から名前空間 URI を取得するメソッドです。 これを用いて getNamespaceURISimply(String) の実装は以下のようになります:
protected String getNamespaceURISimply(String prefix) { // prefix bound on the current node String uri = getNamespaceURILocally(prefix); if(uri != null) return uri; // prefix bound on a parent node return getParentContext().getNamespaceURI(prefix); }
getPrefixSetSimply(String) メソッドの実装
getPrefixSetSimply(String) の実装も getPrefixSetSimply(String) と概ね同じです。 親ノードを使わずに名前空間 URI から接頭辞のセットを取得するメソッドを定義します:
protected abstract Set<String> getPrefixSetLocally(String uri);
これを用いた getPrefixSetSimply(String) の実装は下でまとめて載せておきます。
定義された抽象メソッド
新に定義された抽象メソッドは以下の3つです:
/** * 親ノードの NamespaceContext を返します。 * 親ノードがない場合は EmptyContext.INSTANCE を返します。 */ protected abstract NamespaceContext getParentContext(); /** * 引数の文字列で指定される接頭辞に対応する名前空間 URI を返します。 * 祖先要素には遡りません。 * 該当する名前空間 URI が見つからなかった場合、null を返します。 */ protected abstract String getNamespaceURILocally(String prefix); /** * 引数で指定される名前空間 URI に対応する接頭辞を返します。 * 祖先要素には遡りません。 * 該当する接頭辞が見つからなかった場合、空の Set を返します。 */ protected abstract Set<String> getPrefixesLocally(String uri);
AbstractNamespace クラスの2つの抽象メソッドは新に実装する必要はありません。
Java コード
AbstractCompositeNamespaceContext の具体的な実装は以下のようになります:
import java.util.*; import javax.xml.namespace.NamespaceContext; /** @author waman */ public abstract class AbstractCompositeNamespaceContext extends AbstractNamespaceContext{ /** * 親ノードの NamespaceContext を返します。 * 親ノードがない場合は {@link EmptyNamespaceContext#INSTANCE} を返します。 */ protected abstract NamespaceContext getParentContext(); protected String getNamespaceURISimply(String prefix) { // prefix bound on the current node String uri = getNamespaceURILocally(prefix); if(uri != null) return uri; // prefix bound on a parent node return getParentContext().getNamespaceURI(prefix); } /** * 引数の文字列で指定される接頭辞に対応する名前空間 URI を返します。 * 祖先要素には遡りません。 * 該当する名前空間 URI が見つからなかった場合、null を返します。 */ protected abstract String getNamespaceURILocally(String prefix); protected Set<String> getPrefixSetSimply(String uri){ Set<String> prefixes = new HashSet<String>(); Iterator<?> ite = getParentContext().getPrefixes(uri); while(ite.hasNext()){ String prefix = (String)ite.next(); String u = getNamespaceURILocally(prefix); if(u == null || u.equals(uri)) prefixes.add(prefix); } prefixes.addAll(getPrefixesLocally(uri)); return prefixes; } /** * 引数で指定される名前空間 URI に対応する接頭辞を返します。 * 祖先要素には遡りません。 * 該当する接頭辞が見つからなかった場合、空の Set を返します。 */ protected abstract Set<String> getPrefixesLocally(String uri); }