- PR -

Node.getNodeValue(); から取得される値について。

投稿者投稿内容
harumaki
常連さん
会議室デビュー日: 2004/09/09
投稿数: 32
投稿日時: 2004-09-10 13:54
それらを実行することによって以下の値がしゅとくされます。

name:[c4] table:[t4] width:[9] seq:[1] search:[1]
name:[c5] table:[t5] width:[90] seq:[2] search:[1]
name:[c6] table:[t6] width:[90] seq:[3] search:[1]
name:[c2] table:[t2] width:[90] seq:[4] search:[1]
name:[c7] table:[t7] width:[90] seq:[5] search:[1]
name:[c1] table:[t1] width:[90] seq:[6] search:[1]
name:[c3] table:[t3] width:[90] seq:[9] search:[1]

colmun "c4" だけ"90" ではなく"9" が取得されます。
xml のcolmun エレメントの順番を変えると4 番目のcolmun エレメントの値が壊れ、
colmun "c4" はちゃんと"90" が取得されます。

なおxml についてはデータ量が多いので多少削りましたが、動作は同じです。
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2004-09-10 14:02
「値が取得されます」とありますが、ここはどのようにコーディングしているのですか?
ここが一番知りたかったところなんですが。
harumaki
常連さん
会議室デビュー日: 2004/09/09
投稿数: 32
投稿日時: 2004-09-10 14:15
transform した時点で値が壊れているのですが。。。

一様記述しますと、
java ソースに以下のものを追記してください。

// ルート要素を取得(タグ名:settings)
Element settingsElem = doc.getDocumentElement();
// colmun要素のリストを取得
NodeList colmunNl = settingsElem.getElementsByTagName( "colmun" );

// colmun要素の数だけループ
int loopNum = colmunNl.getLength();
for ( int cnt = 0; cnt < loopNum ; cnt++ ) {

 // colmun要素を取得
 Element colmunElem = (Element)colmunNl.item( cnt );

 // width要素のリストを取得
 NodeList widthNl = colmunElem.getElementsByTagName( "width" );
 // width要素を取得
 Element widthElem = (Element)widthNl.item( 0 );
 // width要素の最初の子ノード(テキストノード)の値を取得
 結果 = widthElem.getFirstChild().getNodeValue();

 System.out.println( "width: [" + 結果 + "]" );
}

といったところです。
けむ
常連さん
会議室デビュー日: 2003/09/26
投稿数: 40
投稿日時: 2004-09-10 15:34
こんにちは。
引用:
結果 = widthElem.getFirstChild().getNodeValue();


widthElemが持つ子要素の数を確認しましたか?
テキストノードが分割されているのではないでしょうか?
harumaki
常連さん
会議室デビュー日: 2004/09/09
投稿数: 32
投稿日時: 2004-09-10 16:08
けむ 様、お返事ありがとうございます!

おっしゃるとおりかもしれません。
子要素(というより子ノードですね)が分割されているような雰囲気です。
数の取得方法がわからなかったので断言できませんが、メモリを見ると分割されていました。
(子ノードの数を取得する方法はないのでしょうか?
Element#getNextSibling() で次々と連結していくのが常套手段なのでしょうか?


なぜこの項目だけ(colmun やtable はかなり長い文字列なのに)分割されるのでしょうか?
分割を回避する方法はないのでしょうか?

質問ばかりで申し訳ありませんが、ご存知の点がありましたらお教え頂けますでしょうか。
harumaki
常連さん
会議室デビュー日: 2004/09/09
投稿数: 32
投稿日時: 2004-09-10 16:35
とりあえず今回の問題はプログラムの方を変更することで解決しました。

widthElem を取得した後の処理を

// width要素の最初の子ノード(テキストノード)の値から全ノードの値を連結
for ( Node n = widthElem.getFirstChild(); n != null; n = n.getNextSibling() ) {
 結果 += n.getNodeValue();
}

System.out.println( "width: [" + 結果 + "]" );

に変更しました。

が、上記の点は依然解決しておりません。
引き続きよろしくお願いいたします。
(特になぜこの値だけ子ノードが分割されるのか?について。
るぱん
ぬし
会議室デビュー日: 2003/08/01
投稿数: 1370
投稿日時: 2004-09-10 16:40
るぱんです。

憶測ですが、
n.text()ってメソッドでとれません?
無かったかな・・・?汗
harumaki
常連さん
会議室デビュー日: 2004/09/09
投稿数: 32
投稿日時: 2004-09-10 17:15
るぱん さま、ご意見ありがとうございます!

Node#text() はありません。
が!
ご意見を頂き調べていたところ発見しました、Node#nomalize()。
引用:

この Node のサブツリーの最深部までに存在するすべての Text ノード (属性ノードを含む) を、Text ノードが構造 (要素、コメント、処理命令、CDATA セクション、エンティティ参照など) のみによって分離される、「通常」形式に直します。その結果、隣接するText ノードも空の Text ノードも存在しない状態になります。この操作は、文書の DOM ビューを保存後ロードし直した状態にすることができるという点で、特定の文書ツリー構造に依存する操作 (XPointer ルックアップなど) を行う必要がある場合に便利です。文書に CDATASections が含まれる場合、この normalize 操作のみが正しく行われない可能性があります。これは、XPointer が Text ノードと CDATASection ノードを区別しないからです。



難しいことが書いてありますが、テキストノードの分離が行われなくなると。
これをtransform してDocument にキャストした直後にかませばよいわけです。
これで不安なくこの処理を使えます。

質問の回答は引き続きよろしくお願い致します。

スキルアップ/キャリアアップ(JOB@IT)