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