- - PR -
DOMのappendChildについて
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-03-16 01:03
今、XMLマスタープロフェッショナル(アプリケーション)の勉強をしています。
DOMのappendChildの説明に 「追加する要素がすでにDOMツリーにある場合存在するノードを削除して追加する」 とあるのですが、いまいち理解できていません。 例えば内容がabcのcode要素をappendしたあとに 内容をdefにしたcodeを要素をappendしたら 結果は後者の内容が出力されると思ったら、 <code>abcdef</code>というような結果になってしまいました。 どなたか詳しい方がいたら、appendChildについて 教えてください。 | ||||||||
|
投稿日時: 2007-03-16 10:47
どうやって「内容をdefに」しましたか?
コードを提示すると問題解決も早いですよ。 | ||||||||
|
投稿日時: 2007-03-16 18:24
返答ありがとうございます。
元のxmlソール文書は以下のとおりです。 <?xml version="1.0" encoding="Shift_JIS" ?> <product><name>冷蔵庫</name><price>150000</price></product> これに対し以下のDOMを実行します。 //////////////////////////////////////////////// import org.w3c.dom.*; import javax.xml.parsers.*; public class aaa{ public static void main(String args[]){ try{ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse("aaa.xml"); //ルート要素を取得する Element root = doc.getDocumentElement(); //要素ノードを作成する Node mNode = doc.createElement("name"); //要素ノードをDOMツリーへ追加 root.appendChild(mNode); //表示用 String data = printTree(root); System.out.println(data); }catch(Exception e){ System.err.println(e.toString()); } } private static String printTree(Node node){ StringBuffer outbuff = new StringBuffer(); int type = node.getNodeType(); if(type == Node.ELEMENT_NODE){ //要素名を取得 String name = node.getNodeName(); //属性ノードを取得する NamedNodeMap attrs = node.getAttributes(); int attr_cnt = attrs.getLength(); StringBuffer attrBuf = new StringBuffer(); for(int i=0; i< attr_cnt; i++){ Attr attr =(Attr)attrs.item(i); attrBuf.append(" "); attrBuf.append(attr.getName()); attrBuf.append("=\""); attrBuf.append(attr.getValue()); attrBuf.append("\""); } //子ノードリストを取得する NodeList children = node.getChildNodes(); //子ノードの数を取得する int count = children.getLength(); if( count != 0){ outbuff.append("<" + name + attrBuf.toString() + ">"); for(int i=0; i<count; i++){ //子ノードを1つ取得する Node child = children.item(i); //再帰呼び出しを行う outbuff.append(printTree(child)); } outbuff.append("</" + name + ">"); }else{ outbuff.append("<" + name + attrBuf.toString() + "/>"); } }else if(type == Node.TEXT_NODE){ String value = node.getNodeValue(); outbuff.append(value); } return outbuff.toString(); } } ////////////////////////////////////////////// このDOMを実行するとname要素が置き換わるイメージなのですが どうぞよろしくお願いします。 | ||||||||
|
投稿日時: 2007-03-16 22:30
このコードの場合、追加している mNode は新規に作ったノードですから、DOMツリーの中には入ってません。「<name>冷蔵庫</name>」に相当するノードは、mNode とは別に DOM ツリーの中に存在します。ですので、appendChild() しても置き換わったりしませんです。 | ||||||||
|
投稿日時: 2007-03-16 23:51
スフレさんありがとうございます!!!
新規追加でも同じ要素名であれば置き換えてしまうものと 勘違いしていました。 大変たすかりました。 最初の質問と記述したコードがめちゃめちゃですね。すいません。 混乱しているようです。。 同じノードに対してtextノードを2回追加しているだけでした・・・ このような感じでしょうか。(特に質問ではございません) ////////////////////////////////////////////////////////// //ルート要素を取得する Element root = doc.getDocumentElement(); Node n2 = root.getFirstChild(); //要素ノードを作成する Element a = doc.createElement("name"); //text作成 Node text = doc.createTextNode("test"); //text追加 a.appendChild(text); //要素ノードをDOMツリーへ追加 root.appendChild(a); //もう一回追加。 Node text2 = doc.createTextNode("test2"); a.appendChild(text2); root.appendChild(a); ////////////////////////////////////////////////////////////// | ||||||||
|
投稿日時: 2007-03-18 16:10
くくりの文言が「(特に質問ではございません)」ですので解決していると思われますが気になる部分があるので……
まず、再投稿されたソースコードでは、パーサの使用方法は正しくなっていますが、スフレさんが指摘された内容が反映されていません。 新たな要素を追加するという動作が変更されていないため、修正されたコードでは以下のような出力になるはずです。 (実行して以下のようになることを確認しました。パーサの設定で本来改行は入りませんが長いため改行しています)
XMLは同一パスのノードが複数存在することを許します。 このため、同一名であっても新規であるノードをappendChildで追加しようとすると、 新たに同じ名前のノードを追加するという動作を行います。 上記から、置き換えたい場合は置き換えたいノードを取得し、テキストノードの値を変更するという手順を踏む必要があります。 あと、以下のコードで標準出力することが出来ます。 投稿前に確認が出来なかったものと推察します。これで多少確認が容易になるかもしれません。
以下はスレッドを読んでいて気になって試してみたことですが、 同一レベルのテキストノードにテキストノードを追加すると、ノードの値が追加されてゆきました。 実用性がないので小ねたにしかなり得ませんが。 | ||||||||
|
投稿日時: 2007-03-20 00:43
暁さん、コメントありがとうございます。
最後に投稿したのは、スフレさんに回答していただいたものを反映 したのではなく、最初の投稿で質問している内容をソースで表現 していたものでした・・・ わかりづらくてもうしわけございません。 まさに 『同一レベルのテキストノードにテキストノードを追加すると、ノードの値が追加されてゆきました。』 という動作のことです。 お手数をおかけしてしまう形になりましたが 『このため、同一名であっても新規であるノードをappendChildで追加しようとすると、 新たに同じ名前のノードを追加するという動作を行います。』 というコメントのおかげで非常に理解がクリアになりました。 ありがとうございました。 |
1