倭マン's BLOG

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

名前空間の暗黙的取り扱い (1) -- 名前を文字列で指定してノードを生成するメソッド

dom4jXML 名前空間をサポートしているので、要素や属性を生成・指定する際には、通常 QName を使用する必要があります。 ただし、毎回 QName を用いて生成・取得を行うのは手間なので、文字列 (java.lang.String) を用いてこれらを行う方法が提供されています。 しかし、文字列を用いて要素や属性の生成・取得を行う際でも、暗黙的に名前空間が指定されています。 今回から何回かにわたって、それらを見ていきましょう(一覧)。

DocumentHelper#createXxxx() メソッド


今回は org.dom4j.DocumentHelper に定義されている createXxxx() メソッドを見ていきます:

  • createQName(String) : QName
  • createElement(String) : Element
  • createAttribute(Element, String, String) : Attribute*1

これらのメソッドでは、全て NULL 名前空間 ("") が設定されます。 

少し注意しなければならないのは、(接頭辞がないにも関わらず)暗黙的に指定されるのがデフォルト名前空間ではないということでしょうか。 デフォルト名前空間とは、対象要素もしくは祖先要素上で、接頭辞なしで宣言された名前空間(xmlns="..." の形の宣言)のことです*2。 これは、どの要素を対象にするかによって変化します。

サンプル


この違いが現れるサンプルを載せておきましょう:

// 準備
Document doc = DocumentHelper.parseText("<parent xmlns='ns'/>");
Element root = doc.getRootElement();

// 名前空間を指定しないで要素を生成
Element child = DocumentHelper.createElement("child");

// 生成した要素を付け加える
root.add(child);

これを実行すると、Document オブジェクト doc が表す XML 文書は

<parent xmlns="ns">
  <child xmlns=""/>
</parent>

となります。 <child> 要素に対して名前空間を指定していないにも関わらず、この要素に名前空間宣言が付加されています*3

*1:第1引数の Element オブジェクトは "owner" とされていますが、DocumentHelper (と同名のメソッドがある DocumentFacotry も)の実装では、この引数は無視されるようです。

*2:対応する宣言がなければ、デフォルト名前空間は「NULL 名前空間」になります。

*3:ただし、この XML 名前空間宣言はオブジェクトノードとして付加されているのではなく、文字列への書き出しの際に付加されています。 特に、Element#declaredNamespaces() メソッドではこのノードを取得することができません。