倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

NamespaceContext の実装を考える (5) : 引数が空文字列のときの挙動

前回までで javax.xml.namespace.NamespaceContext が実装すべきメソッド

  • getNamespaceURI()
  • getPrefixes()
  • getPrefix()

を一通り見ました。 今回は、それらのメソッドに空文字列 ("") を渡したときの挙動を見ていきます(一覧)。

以下で見る挙動は、API ドキュメントに仕様として書かれているものもありますが、それ以外はサンの JDK に含まれる実装(以下、サン JDK)を元にしています。

メソッド getPrefixes(), getPrefix()


これらのメソッドには、引数として名前空間 URI を表す文字列を渡しますが、サン JDK では、これらのメソッドに空文字列を渡すと IllegalArgumentException が投げられます。

仕様上は、引数として null が渡された場合に IllegalArgumentException が投げられるとしかなっていないので、空文字列を渡したときのこの挙動は実装に依存しているんでしょう。

メソッド getNamespaceURI()


名前空間 URI は空文字列でなく、接頭辞が空文字列の場合★


対象となる XML 文書は以下のようなものです:

<a xmlns="xyz">
  <b/>
</b>

この場合は API ドキュメントの仕様により、<a> 要素、<b> 要素どちらでも "xyz" が返されます。

名前空間 URI は空文字列で、接頭辞が空文字列でない場合★

対象となる XML 文書は以下のようなものです:

<a xmlns:p="">
  <b/>
</b>

この名前空間の宣言の仕方は、禁止はされていませんが付属的な扱いになっています*1。 サン JDK では StAX でこの文書を解析すると ParseError が投げられます*2

名前空間 URI も接頭辞も空文字列の場合★

対象となる XML 文書は以下のようなものです:

<a xmlns="">
  <b/>
</b>

この場合、getNamespaceURI() は空文字列を返しそうですが、少なくともサン JDK では null を返します。 名前空間の仕様書では、名前空間宣言で URI を空文字列にすると、「名前空間 URI は値を持たない (the namespace name has no value.)」ことになるので、これは名前空間の仕様にしたがった実装になっているんでしょう。

ちなみに、以下のような XML 文書があった場合

<a xmlns="xyz">
  <b xmlns=""/>
</b>

<b> 要素の NamespaceContext オブジェクト context_b に対して、以下のメソッド呼び出し

context_b.getNamespaceURI("");

を行うと、この場合にも null が返されます。 つまり、<b> 要素では「xmlns=""」によってデフォルト名前空間の宣言が取り消されています(undeclared)。

*1:名前空間の仕様書には「the namespace name may not be empty.」と書かれています。 3 Declaring Namespaces を参照。

*2:ただし NamespaceContext インターフェースと同じパッケージ内にある javax.xml.namespace.QName は名前空間 URI を空文字列、接頭辞を空でない文字列に指定しても、キチンとインスタンス化出来るようです。