竹形誠司 ブログ
Java+MySQL+Tomcat    »トピック一覧
掲示板へのスパムが多いため、「ご質問」のコーナーはユーザー登録制とさせていただきました。お手数ですが、上の「新規ユーザーの登録」メニューより登録をお願いします。
帳票Web
アプリケーション

受注開発始めました
詳しくは こちら
竹形 誠司 著/ラトルズ刊
JSP帳票アプリケーション実践開発入門
JSP帳票アプリケーション
実践開発入門

JSP業務アプリケーション短期開発入門
JSP業務アプリケーション
短期開発入門

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門
Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

Java+MySQL+Tomcatで作る掲示板とブログ
Java+MySQL+Tomcatで作る
掲示板とブログ
org.w3c.domのNodeをElementにキャストできる件
by 竹形 誠司[takegata]
XMLで書いたテンプレートにデータを挿入してPDFの帳票を出力するプログラムを3年前に書いたんですが、利用しているPDFライブラリのiTextがバージョンアップしたのに合わせていろいろ書きなおしているところです。で、自分で書いたはずのプログラムでちょっとハマったのでメモ。

次のようなデータがdata.xmlファイルに保存されているとします。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dataList>
    <data type="string">aaa</data>
    <data type="string">bbb</data>
    <data type="string">ccc</data>
    <data type="int">111</data>
    <data type="int">222</data>
    <data type="int">333</data>
</dataList>
これを次のようなプログラムで読み出します。
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;

public class XmlTest{
    public static void main(String[] args){
        try{
            File file = new File("data.xml");
            DocumentBuilder builder =
                DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = builder.parse(file);
            Element element = document.getDocumentElement();
            NodeList dataList = element.getElementsByTagName("data"); //★1
            for(int i=0;i<dataList.getLength();i++){
                Node data = dataList.item(i); //★2
                NamedNodeMap attributes = data.getAttributes();
                Node nodeItem = attributes.getNamedItem("type");
                String type = nodeItem.getTextContent();//★3
                String dataContent = data.getTextContent();
                System.out.println(type + ":" + dataContent);
            }
        }catch(javax.xml.parsers.ParserConfigurationException e){
            e.printStackTrace();
        }catch(org.xml.sax.SAXException e){
            e.printStackTrace();
        }catch(java.io.IOException e){
            e.printStackTrace();
        }
    }
}
★1の行でgetElementsByTagNameを実行しているのですが、このメソッドが返すのはNodeListという型で、item(i)でi番目のNodeオブジェクトが取得できるんですが、このオブジェクトから属性(上のデータの例では"type")を取り出すには一度、NamedNodeMap を取得して、そこから更にNodeオブジェクトを取得して、やっと属性の値が取り出せる、という感じです。getElementsByTagNameメソッドが素直にElementオブジェクトを返してくれればgetAttributeメソッドで属性の値が取り出せるんですけどねぇ・・・と思っていろいろ調べたらitem(i)の戻り値をElementにキャストしている例がいくつかのページで説明されていました。上のコードの★2〜★3を次のように書くことができます。
    Element data = (Element)dataList.item(i);
    String type = data.getAttribute("type");
4行が2行になったところで「どれだけうれしいのか?」という話ではあるのですが、どうも腑に落ちないのはJava5で導入されたジェネリクスや拡張for文がいまだにサポートされていないことなんですよね。XMLも旬が過ぎてしまったということなんでしょうか。
投稿:竹形 誠司[takegata]/2011年 04月 15日 11時 06分 /更新:2011年 04月 15日 11時 28分