XMLをJSPで再帰処理を使った取得方法とは?

このQ&Aのポイント
  • XMLの処理方法について教えてください。特に、JSPで再帰処理を使ってXMLのノードを取得する方法について知りたいです。
  • JSPで再帰処理を行ってXMLの要素ノードを取得する方法を教えてください。
  • XMLの再帰処理をJSPで行う際にエラーが発生しています。JSP内で要素ノードを取り出して表示する方法を教えてください。
回答を見る
  • ベストアンサー

XMLをJSPで再帰処理を使って処理する方法について

たびたびすみません、XMLの処理をする上でやり方がわからなくなって しまったので、教えていただきたいのですが。。。 XMLのルートノード以下のものを取得する場合、階層がはっきりしてないとき などは、再帰処理をつかってノードを取得するようにしたいと思っているんですが、JSPでの再帰処理がなかなかうまくできないんです。 再帰処理を行うクラスのメソッドが例えば、 public boolean scanEach(NodeList agNode) { try{ for(int nCnt=0;nCnt<agNode.getLength();nCnt++) { node = agNode.item(nCnt) ; if(node.getNodeType() == Node.ELEMENT_NODE){ out.println("『 "+ node.getNodeName() +"』<br>") ; } if(node.hasChildNodes()) blScanEach(node.getChildNodes()) ; } } catch(Exception except) { except.printStackTrace() ; return false ; } return true ; } と要素ノードを取り出すメソッドがあったら、out.printlnの部分が JSP内での宣言じゃないのでエラーになってしまいます。 JSPで取り出して表示できるようにしたいのですが、なにかいい方法が ないか、教えていただけないでしょうか。 再帰処理を使わなくても、例えばどの階層にあるかわからない<タグ>タグを 検索したりする方法が他にあったら、その方法もおしえていただけると ありがたいのですが。。 何度も申し訳ありません。よろしくお願いします。

  • XML
  • 回答数2
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.2

> これで、ブラウザで確認するとテキストノードに[]がついて表示されて > しまいます。 それは、以下の行に原因があるのでしょう。 > if(nodeScan.hasChildNodes()) al.add(scanEach >         (nodeScan.getChildNodes())) ; scanEach() の返り値は ArrayList ですから、ArrayList に ArrayList を追加していることになります。 ArrayList#addAll() メソッドを使いましょう。 if(nodeScan.hasChildNodes()) {   al.addAll(scanEach(nodeScan.getChildNodes())); } # 確認してません (^^;

bibi5555
質問者

お礼

ほんっとに助かりました。 最後の再帰処理のところが問題だったんですね... 仕事でXMLの操作をしなきゃいけないのに、会社には詳しく教えてくれる 人がいないので、結構困り果ててます。 そんななかですごく助かりましたです。ありがとうございました。

その他の回答 (1)

  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.1

とりあえず、質問にあるのと同じ事をするなら、こんな感じでしょうか? > public boolean scanEach(NodeList agNode) { public boolean scanEach(NodeList agNode, javax.servlet.jsp.JspWriter out) { > if(node.hasChildNodes()) blScanEach(node.getChildNodes()) ; if(node.hasChildNodes()) blScanEach(node.getChildNodes(), out) ; とか。 私なら、要素をスキャンしてゆくことと、表示の都合("『" でくくるとか、改行するとか)は、 切り離しておいた方がよろしいので、私なら、ArrayList を渡して、Node を 突っ込んでおいて、JSP 側で利用するか、Iterator を作っちゃうかな。

bibi5555
質問者

補足

回答ありがとうございます!さっそく試してみました. JSPに書き出す処理は上手くいきました. でも、a-kumaさんが言うように表示などをメソッドで指定してしまうと いまいちと思うので、ArrayListの方も試してみました. public ArrayList scanEach(NodeList agNode) {    ArrayList al = new ArrayList() ;    try{   for(int nCnt=0;nCnt<agNode.getLength();nCnt++) { Node nodeScan = agNode.item(nCnt) ; if(nodeScan.getNodeType() == Node.ELEMENT_NODE){        al.add(nodeScan.getNodeName()) ; } if(nodeScan.getNodeType() == Node.TEXT_NODE) {       al.add(nodeScan.getNodeValue()) ; } } if(nodeScan.hasChildNodes()) al.add(scanEach          (nodeScan.getChildNodes())) ; }      }catch(Exception ex) { return al ;   } こんな感じでメソッドを作ってArrayListで受け取ってみました。 arrayList = scanEach(nodeList) ; Iterator itr = arrayList.iterator() ; while(itr.hasNext()) { obj = itr.next() ; out.println(obj +"<br>") ; } これで、ブラウザで確認するとテキストノードに[]がついて表示されて しまいます。 こんな感じです. aaa [すずらん, ddd, [ひまわり]] ccc [ゆうすけ] bbb [さ] このかっこは表示のときに取り除くことはできるのでしょうか また、子ノードの中に入ってる孫ノードが子ノードと一緒になってしまうのですが これをバラバラにすることはできるんでしょうか?? 教えて下さい、お願いします.

関連するQ&A

  • 中身が一部しかわかっていないXMLの読み方

    XML例 <A> <B> bbb </B> <C> <D> ddd </D> </C> </A> C#でXMLを読み、特定のタグの中身を書き換える処理を実装しようしています。 ただしXMLファイルの中に書き換えたいタグ以外にどんなタグがあるかがわかっていません。 上記の例の場合、 「<A> - <C> - <D>のdddを書き換えたい」ということはわかっています。 この場合どのように行うのがよいでしょうか? ネットでのソースを参考に書き換えたい値のタグが見つかるまで再帰処理を行い タグが見つかった場合値を書き換えるような処理を書いてみました。 よくあるやり方や、もっとスマートな方法が有りましたらご教授お願いします。 また直接関係なくともヒントとなるようなものでも結構です。 よろしくお願いします。 void test() { XmlDocument document = new XmlDocument(); // ファイルから読み込む document.Load(filePath); readXML(document.DocumentElement); } void readXML(XmlNode node) { // if(node.Name == "D") // 書き換えたい値のタグか判定する //{ // 値を書き換える処理 //} if (node.HasChildNodes) { node = node.FirstChild; while (node != null) { readXML(node); node = node.NextSibling; } } }

  • JSPでXMLのデータ表示がしたいです

    XMLについてわからないことが多くて、困っています。 質問したいのですが、 JSPの画面でXMLのデータを表示させたいと思っています。 全部のデータを表示という場合、getDocumentElement()メソッドが あると思うのですが、例えばテキストノードのみを表示させたい場合、 <タグ>などのノードから、全テキストノードを一気に拾い出す方法は あるのでしょうか?メソッドとか。 ただ表示させるだけではなくて、データの削除とか変更などのデータ加工 もしていきたいので、最適なデータの表示がしたいんです。なので、操作 をしやすい取り出し方というか。。。 漠然とした質問で申し訳ありませんが、詳しい方がいましたら教えてもらえ ないでしょうか?お願いします。

    • ベストアンサー
    • XML
  • 再帰メソッドについて

    いつもお世話になっております。 再帰メソッドについて質問があります。 後述のプログラム実行後、以下の結果が 得られました。 ********** depth = [0] , value = [0] ********** depth = [1] , value = [1] ********** depth = [2] , value = [2] ########## depth = [2] , value = [3] …★ ########## depth = [1] , value = [3] recursionMethod() は3回呼ばれました。 (以下、ソース) public class RecursionTest { private static final int MAX_DEPTH = 2; private static int cnt = 0; private int val =0; public static void main(String[] args) { // 再帰メソッドの呼び出し RecursionTest own = new RecursionTest(); own.recursionMethod(0); System.out.println("\n recursionMethod() は" + cnt + "回呼ばれました。"); } private void recursionMethod(int depth) { // 再帰メソッドが呼ばれた回数をカウントする cnt++; System.out.println("********** depth = [" + depth + "] , value = [" + val + "]"); val++; // パラメータ depth が MAX値に到達したら、return する if (depth++ >= MAX_DEPTH) { return; } // 自分自身の呼び出し recursionMethod(depth); System.out.println("########## depth = [" + depth + "] , value = [" + val + "]"); } } 実行結果の★以降が得られる理由が全く分かりません。 ・return で main() に戻るはずなのになぜ「###~」のログが出力されるのか ・depth の値がなぜデクリメントされるのか (誰がデクリメントの処理をしているのか) そもそも上記の結果を返すことが「メソッドの再帰的呼び出し」ということなのでしょうか? ご教授頂ける方がいらっしゃいましたら、宜しくお願い致します。

    • ベストアンサー
    • Java
  • XMLファイルの読込み方法についての質問

    こんにちは、mako-kwnshと申します。 あるXMLを読み込んで指定したノード内 のデータを取り込んだ後、 指定したノードをnode型のデータに 代入したいのですが、 やり方がいまいちわかりません。 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.parse("c:\\Scenario\\test1.xml"); Element xmlroot = doc.getDocumentElement(); //String first = xmlroot.getNodeName(); // EMSData d3aData = new EMSData(att); // System.out.println("ddd" + d3aData.getValue(D3aCommonInfoPath.SYSTEM_KIND)); // System.out.println("ddd" + xmlroot);

    • ベストアンサー
    • Java
  • 再帰処理を非再帰処理に書き換える場合

    TreeViewなど階層数・要素数が動的に変化し それらすべての要素に対して一括処理をするといった 本質的に、真に再帰的な操作をしなければならないような場合なのですが 状況説明のため少ないメンバに絞ると こんなノードの抽象クラスがあるとします namespace TreeView { namespace Node { class Super; }} class MemoryMap; class TreeView::Node::Super { protected: typedef Super* PTR; PTR next, child; Super(); virtual ~Super(); virtual Void Save( MemoryMap* ) const = 0; public: static Void Release( PTR* pp ); template <class T> static Void Release( T** pp ){ Release( (PTR*)pp ); } }; んで using TreeView::Node::Super; Super::Super() : next(NULL), child(NULL){} Super::~Super(){} こんな感じにしといて、任意に追加、挿入しときますと その後一括解放のためのReleaseの本体は Void Super::Release( PTR* pp ){ for ( PTR p; p = *pp; ){ if ( p->child ) Release( &p->child ); *pp = p->next; delete p; } } こんな感じで、再帰を使えば結構簡単に書けると思うのですが ・・・利用法から考えてよっぽどないとは思うのですが やはりそこは一応 スタックオーバーフローの危険性をコードサイドから積極的に ほぼ回避しておくべきと考えると 階層数の上限を設けておいて 最低、追加・挿入時には、それをチェックする というのが良いかと思うのですが 仮に別のアプローチで こういった類の再帰(もっと複雑な場合のが多いかも)を非再帰関数に直すには やっぱり ・goto文 ・自分でヒープ上などに作る疑似スタック ・そのスタックに、gotoのジャンプ位置を保存できるenumとかの定数フラグ などを使用せざるを得ない って感じになってくるんでしょうかね?

  • ServletからJSP

    はじめまして。 お世話になります。 以下のようにサーブレットから条件によってJSPファイルを 使い分けようと思っているのですが、うまく出来ません。   protected void processRequest(HttpServletRequest request, HttpServletResponse response)   throws ServletException, java.io.IOException   {     PrintWriter out = response.getWriter();     out.println("<html>");     out.println("<head>");     out.println("<title>タイトル</title>");     out.println("</head>");     out.println("<body>");     RequestDispatcher rd = null;     if(/* 条件1 */)     {       rd = request.getRequestDispatcher("hoge1.jsp");     }     else if(/* 条件2 */)     {       rd = request.getRequestDispatcher("hoge2.jsp");     }     else     {       rd = request.getRequestDispatcher("hoge3.jsp");     }     out.println("</body>");     out.println("</html>");     if(rd != null)     {       rd.include(request,response);     }   } このようにすると <html> ・ ・ サーブレットから出力した部分 ・ </html> <****> JSPで出力した部分 </****> とサーブレットの部分だけ先に出力されてしまいます。 JSPファイルの前後に出力させるにはどのようにすればよいのでしょうか。 よろしくお願い致します。

    • ベストアンサー
    • Java
  • メソッドの再帰呼び出しについて

    再帰処理に関する質問をさせていただきます。私は今複数のarraylistの中に入っているオブジェクトを順列を用いてすべての並びを所得するプログラムを作っています。プログラムが長く汚いので(汗)、例で示させていただきます。 (例) ArrayList t1; ArrayList t2; t1の中身[obj1,obj2] t2の中身[obj3,obj4] 結果:以下のように4つオブジェクトを作成 [obj1,obj3],[obj1,obj4],[obj2,obj3],[obj2,obj4] それに伴い、メソッドを作り再帰呼び出しを行っているんですが、returnでメインに返りません。戻り値はvoidです。また、 return; System.out.println("check"); と書くと、checkが出力されてしまっています(しかも何個も)。IndexOutOfBoundsExceptionのエラーがでるのですが、先にreturnを処理するはずなのになぜだろうと悩んでいます。 return以外にメインに戻る方法はあるんでしょうか?またreturnでメインに戻らない理由を知っている方がいるなら、ぜひ教えていただきたいです。よろしくお願いします。

  • EXCELVBA XML処理

    こんにちは、 下記のプログラムを作成したのですが、 (すいません、わかりづらいかもしれません。) <DIMENSION Name="E1">内の<HIERARCHY>タグ内にある <PARENT>と<CHILD>の値をセルに貼り付けようとしているのですが、 現在、下記二点で悩んでいまして、何か方法などありましたらお願い致します。 1:<DIMENSION Name="E1">処理のときに、セルにNAMEの値E1を出力  しているのですが、二回表示されてしまう。  (おそらく、<MEMBERS>と<HIERARCHY>と二つタグがあるので  そのせいかと思ったのですが、回避方法が変わりません。) 2:<DIMENSION Name="E1">だけでよいのだが、  <DIMENSION Name="Z1">まで処理を行っている  (<DIMENSION Name="E1">を抜けたという判断方法がわからず・・) VBAコード----------- Option Explicit Dim ia As Long Dim flg As Integer Private Sub CommandButton2_Click() Const cnsTITLE = "テキストファイル読み込み処理" Const cnsFILTER = "全てのファイル (*.*),*.*" Dim xlAPP As Application ' Applicationオブジェクト Dim strXMLFile As String Dim objDOM As MSXML2.DOMDocument Dim rtResult Set xlAPP = Application xlAPP.StatusBar = "読み込むファイル名を指定して下さい。" strXMLFile = xlAPP.GetOpenFilename(FileFilter:=cnsFILTER, _ Title:=cnsTITLE) If StrConv(strXMLFile, vbUpperCase) = "FALSE" Then Exit Sub Set objDOM = New MSXML2.DOMDocument rtResult = objDOM.Load(strXMLFile) If rtResult = True Then ia = 0 flg = 0 procDispDatas objDOM.childNodes Else MsgBox "読み込み失敗" End If Set objDOM = Nothing End Sub Sub procDispDatas(objNode) Dim obj For Each obj In objNode If (obj.parentNode.nodeName = "DIMENSION") Then '<DIMENSION >タグ内処理か判断 If (obj.parentNode.Attributes.getNamedItem("Name").nodeValue = "E1") Then '<DIMENSION Name="E1">タグ内処理か判断 ia = ia + 1 Cells(ia, 1).Value = _ obj.parentNode.Attributes.getNamedItem("Name").nodeValue & " : " flg = 1 End If ElseIf (flg = 1) Then If (obj.parentNode.nodeName = "HIERARCHY") Then '<HIERARCHY>タグ内処理か判断 flg = 2 End If ElseIf (flg = 2) Then If (obj.parentNode.nodeName = "NODE") Then '<NODE>タグ内処理か判断 flg = 3 End If ElseIf (flg = 3) Then Select Case obj.parentNode.nodeName Case "PARENT" '<PARENT>タグ内処理か判断 ia = ia + 1 Cells(ia, 1).Value = _ obj.parentNode.nodeName & " : " & _ obj.nodeValue Case "CHILD" '<CHILD>タグ内処理か判断 ia = ia + 1 Cells(ia, 1).Value = _ obj.parentNode.nodeName & " : " & _ obj.nodeValue Case Else End Select End If If obj.hasChildNodes Then procDispDatas obj.childNodes End If Next End Sub XMLファイル---------- <?xml version = "1.0" encoding="UTF-16" ?> <HSDATA> <DIMENSION Name="E1"> <MEMBERS> <MEMBER> <LABEL>[None]</LABEL> <AT Name="DefCurrency">[None]</AT> <DESCRIPTION Language="English">[None]</DESCRIPTION> </MEMBER> </MEMBERS> <HIERARCHY> <NODE> <PARENT>#root</PARENT> <CHILD>[None]</CHILD> </NODE> <NODE> <PARENT>#root</PARENT> <CHILD>MNG_CN</CHILD> </NODE> </HIERARCHY> </DIMENSION> <DIMENSION Name="Z1"> <HIERARCHY> <NODE> <PARENT>abc</PARENT> <CHILD>123</CHILD> </NODE> <NODE> <PARENT>def</PARENT> <CHILD>456</CHILD> </NODE> </HIERARCHY> </DIMENSION> </HSDATA>

  • LinuxでのJSPによるXML文書表示の際の文字コードについて

    Windowsで作ったXML操作のJSP(Servletと連携してます)を、Linuxのサーバー において、動作させたいと思っています。 Linuxは全く初めてなので、教えていただきたいのですが。。 XMLを再帰処理で読みこんで、ツリー構造で表示するところが、Windowsだと エラーなくできるのですが、Linuxだとjspの再帰処理の部分でソースコードのエラー (try{}catch{}の}が閉じられていないなどの)エラーになってしまいます。 Windowsのソースコードのままなので、"}"が閉じられていないというのは考えにくいので、 おそらく文字化けのエラーだと思っています。 jspのディレクティブのところは、"Shift_JIS"の部分を"EUC-JP"に変えて <%@ page pageEncoding="EUC-JP" contentType="text/html; charset=EUC-JP" ・・・・%> としたんですが、これだけでは足りないでしょうか? 再帰処理の表示のところでも、文字コードの設定が必要とか。。。 あと、画面で入力された文字はWindowsだとメソッド内で new String(string.getBytes("8859_1"), "Shift_JIS").trim(); としているんですが、"Shift_JIS"を"EUC_JP"に変えるとして、"8859_1"の部分は 変えなくて良いでしょうか?? 初歩的な質問ばかりですみません。。Linuxのことを詳しく書いてある本が会社になくて、 (Linuxの本はあっても、肝心の知りたいことが書いてなかったりするので) できればLinuxでjavaを扱うサイトやLinuxでXMLを扱うオススメのサイトを知っていたら、ぜひぜひ教えてほしいのですが☆ よろしくお願いします。

    • ベストアンサー
    • Java
  • JavaによるXMLの読み込みについて

    現在、JavaでXMLを読みたく色々なサイト様を参考にさせて頂き プログラムを作成しております。 その結果、下記のようなプログラムで要素名を取得することは出来たのですが、 「属性名」と「属性の値」を読み込み表示することが中々上手くいきません。 どこに何を追加したらよいでしょうか。宜しければ教えて下さい。 -- sample.java -- sample.xml -------------------------------------- import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; import java.io.*; public class sample { public static void main(String[] argv) { sample a = new sample(); a.runner(); } final static String file = "sample.xml"; public void runner() { DocumentBuilderFactory factory; DocumentBuilder builder; Node root; try { factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); factory.setIgnoringElementContentWhitespace(true); factory.setIgnoringComments(true); factory.setValidating(true); root = builder.parse(file); showNodes(root, " "); } catch (ParserConfigurationException e0) { System.out.println(e0.getMessage()); } catch (SAXException e1){ System.out.println(e1.getMessage()); } catch (IOException e2) { System.out.println(e2.getMessage()); } } public void showNodes(Node node, String space) { NodeList nodes = node.getChildNodes(); for (int i=0; i<nodes.getLength(); i++) { Node node2 = nodes.item(i); if(!node2.getNodeName().equals("#text")){ System.out.println(space + "<" + node2.getNodeName() + ">"); showNodes(node2, space + " "); } } } }

    • ベストアンサー
    • Java

専門家に質問してみよう