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要素の内容となる。

