目次へ

7.3. XMLを作成する

次に、名前空間が指定されているXML文書を書いてみましょう。名前空間付のノードを生成したり操作する場合は、XML文書を読む場合と同様に"NS"のついたメソッドを使用します。以下、Elementノードに提供されているメソッドです。

メソッド 内容
public Element createElementNS(String namespaceURI,
String qualifiedName)

所定の修飾名とネームスペース URI を持つ要素を作成します。

public Attr createAttributeNS(String namespaceURI,
String qualifiedName)

所定の修飾名とネームスペース URI を持つ属性を作成します。

public void setAttributeNS(String namespaceURI,
String qualifiedName,
String value)

指定されたローカル名およびネームスペース URI を持つ属性を追加します。属性値は3番目の引数で指定されたものになります。

public void removeAttributeNS(String namespaceURI,
String localName)

ローカル名とネームスペース URI を指定して属性を削除します。

public Attr setAttributeNodeNS(Attr newAttr)

新しい属性を追加します。指定したローカル名およびネームスペース URI の属性がすでに要素内に存在する場合、新しい属性で置き換えられます。

ただし、デフォルト名前空間や名前空間接頭辞を宣言する属性は、通常の属性と同様にDOMツリーに追加していく必要があります。さらに、DOMではNamespaceURIと接頭辞の関係を管理していません。つまり、指定された名前空間URIを読み込んで、適当な名前空間接頭辞を付加する、などの作業はアプリケーションできちんと実装しなければいけません。

例を見ていきましょう。以下のようなXML文書があります。

   <?xml version="1.0" encoding="EUC-JP"?>
   <html xmlns="http://www.w3.org/1999/xhtml">
   <body>
   <form action="/sample2/productInput.jsp" method="post">
   <table>
   <tr>
   <td>商品名</td>
   <td>
   <input type="text" name="name"/>
  </td>
  </tr>
  </table>
  </form>
  <html:form action="/sample/productInput.do" method="post" xmlns:html="http://jakarta.apache.org/struts/tags-html-1.0">
  <table>
  <tr>
  <td>商品名</td>
  <td>
  <html:input type="text" property="property"/>
  </td>
  </tr>
  </table>
  </html:form>
  </body>
  </html>

上のXML文書を出力するプログラムは以下のようになります。

  1  import org.w3c.dom.DOMImplementation;
  2  import org.w3c.dom.Document;
  3  import org.w3c.dom.Element;
...
 19  public class WriteJSPFile{
 20      
 21      public static void main(String args[]) throws Exception{
 22          String xhtml_namespace_uri="http://www.w3.org/1999/xhtml";
 23          String htmltag_namespace_uri="http://jakarta.apache.org/struts/tags-html-1.0";
 24          String xmlns_namespace_uri="http://www.w3.org/2000/xmlns/";
 25    
 26          DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); 
 27          factory.setNamespaceAware(true);
 28          DocumentBuilder builder=factory.newDocumentBuilder(); 
 29          DOMImplementation domImpl=builder.getDOMImplementation();
 30          Document document=domImpl.createDocument(xhtml_namespace_uri,"html",null);
 31  
 32          Element html=document.getDocumentElement();
 33  
 34          Attr xhtmlDeclare=document.createAttributeNS(xmlns_namespace_uri,"xmlns");
 35          xhtmlDeclare.setValue(xhtml_namespace_uri);
 36          html.setAttributeNodeNS(xhtmlDeclare);
…
 41          Element form=document.createElementNS(xhtml_namespace_uri,"form");
 42          body.appendChild(form);
 43  
 44          Attr action=document.createAttributeNS(null,"action");
 45          action.setValue("/sample2/productInput.jsp");
 46          form.setAttributeNodeNS(action);
 47  
…
 76          Element formWithPrefix=document.createElementNS(htmltag_namespace_uri,"form");
 77          body.appendChild(formWithPrefix);
 78  
…
 86  
 87          Attr htmlTagDeclare=document.createAttributeNS(xmlns_namespace_uri,"html");
 88          htmlTagDeclare.setPrefix("xmlns");
 89          htmlTagDeclare.setValue(htmltag_namespace_uri);
 90          formWithPrefix.setAttributeNodeNS(htmlTagDeclare);
 91  
 92          formWithPrefix.setPrefix("html");
 93  
 …
120          Transformer transformer = transFactory.newTransformer();
121          transformer.setOutputProperty(OutputKeys.INDENT,"yes");
122          transformer.setOutputProperty(OutputKeys.ENCODING,"EUC-JP");
123          DOMSource source = new DOMSource(document);
124          StreamResult result = new StreamResult(System.out); 
125          transformer.transform(source, result);
126  
127      }
128      
129  }

 まず、30行目でDOMImplementationのcreateDocumentメソッドを使用して、Documentノードを生成しています。createDocumentメソッドは、1番目の引数にDocumentノードの名前空間を指定します。これは、ルート要素の名前空間にもなります。ルート要素htmlは、"http://www.w3.org/1999/xhtml"名前空間に属します。ここでも第1引数に"http://www.w3.org/1999/xhtml"を指定します。32行目で、ルート要素htmlを取得していますが、htmlの名前空間URIは"http://www.w3.org/1999/xhtml"になります。

 次に、html要素にデフォルト名前空間を宣言する属性を追加しています。34行目で、createAttributeNSメソッドを使用し、xmlns属性を作成しています。xmlns属性の名前空間URIには、"http://www.w3.org/2000/xmlns/"を指定します。名前空間を宣言する属性は、"http://www.w3.org/2000/xmlns/"というURIで表される名前空間に属しますので、このURIを指定してください。35行目で"xmlns"属性の値を、"http://www.w3.org/1999/xhtml"に設定しています。そして、36行目でsetAttributeNodeNSメソッドを使用して、html要素に属性を付加しています。ここで、ひとつ注意してください。名前空間を使用している場合、属性を付加する際には"setAttributeNode"メソッドではなく、"setAttributeNodNS"メソッドを使用しましょう。これにより、名前空間とローカル名が両方とも一致するような属性を、重複して設定することを防ぐことができます。以上の操作により、デフォルト名前空間は"http://www.w3.org/1999/xhtml"に設定されました。

 最初のform要素(XML文書4行目)は名前空間接頭辞を持ちません。よって、デフォルト名前空間"http://www.w3.org/1999/xhtml"に属することになります。41行目で、createElementNSメソッドを使用してform要素を作成し、42行目でDOMツリーに付加しています。また、form要素のaction属性も名前空間接頭辞を持ちません。これは、要素毎の区画に属する属性になります。createAttributeNSを使用して、action属性を生成します。名前空間URIにはnullを指定します。

 2つめのform要素には、名前空間接頭辞がついています。名前空間接頭辞を付加するには、NodeのsetPrefixメソッドを使用します。まず、接頭辞がどの名前空間URIを表すのか、宣言する属性を作成します。87行目で、createAttributeNSメソッドを使用して、名前空間接頭辞を宣言する属性を生成しています。この属性は、名前空間接頭辞"xmlns"、ローカル名"html"をもつ属性です。名前空間接頭辞"xmlns"を持つノードは"http://www.w3.org/2003/xmlns/"名前空間に属します。よって、createAttributeNSメソッドの第1引数には"http://www.w3.org/2003/xmlns/"、第2引数にはローカル名"html"を指定します。次に、88行目で、名前空間接頭辞を指定します。名前空間接頭辞は、"xmlns"になります。89行目で属性値を設定し、90行目で属性ノードをform要素に付加しています。属性を付加するときに、setAttributeNodeNSメソッドを使用している点に注意してください。

 最後に、setPrefixメソッドを使用して、form要素の名前空間接頭辞を設定します。実は、宣言されていない名前空間接頭辞を付加することは可能です。ただし、名前空間URIがnullのノードに名前空間接頭辞をつけようとすると、エラーになります。

 このように名前空間がかかわるXML文書を生成するためには、名前空間の宣言や接頭辞の管理に注意が必要です。名前空間の宣言や接頭辞を名前空間を対応させ、自動的に接頭辞を付加したり、あるいは名前空間宣言を挿入したりする機能は、DOM Level 3には実装される予定です。(DOM Level 3 は今、ワーキングドラフト状態です)。

(実習課題2)

7.3で例に挙げたプログラムを完成させなさい。

解答例はこちら

(実習課題3)

以下のXMLを出力するプログラムを作成しなさい。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<m:customer xmlns:m="http://www.techscore.com/customerMessage/">
<m:name>山田太郎</m:name>
<m:age>31</m:age>
</m:customer>
</soapenv:Body>
</soapenv:Envelope>
  • プログラムの実行時に、顧客名と年齢を指定可能にする。
  • 1番目の引数に顧客名を指定する。指定した顧客名は、name要素の内容となる。
  • 2番目の引数に年齢を指定する。指定した年齢はage要素の内容となる。

解答例はこちら

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp