• ベストアンサー

JavaでのXMLデータ抽出について

いつも、お世話になります。 以前、Perlでも似たような質問をさせていただきましたが、結局、Javaで作ることになりました。ところが、以下の現象が発生して困っております。 プログラムは、下記のXmlファイルを読み込ませ"★"の部分を抽出してくるというプログラムです。 読み込んだ結果として、次のようなものが欲しいとすると、 memoNumber = Class_A MemoNumber = 53 memoNumber = Class_B MemoNumber = 67 : 実際には、以下のようになってしまいます。 memoNumber = Class_A MemoNumber = 53 memoNumber = Class_A MemoNumber = 42 : つまり、"memoNumber"の最初の要素しか見ておらず、次の"MemoNumberList"以下のタグ内を探しに行ってしまうようです。 そこまでは分かったのですが対処法法が分かりません。 読み込ませたいXMLファイルは以下のとおりです(データ数が膨大になるので一部省略をしています) <MemoBlockList> <Class ID="namae1" >★ <Local>1</Local> <AmemoWritingLocationList> <AmemoWritingLocation Length="50" Side="1">★ <CreateID>345.9886776</CreateID> <IDList> <IDNo IDNo="1">★ <MemoNumberList> <MemoNumber memoNumber="Class_A">53</ClassName>★ <MemoNumber memoNumber="Class_B">67</ClassName>★ <MemoNumber memoNumber="Class_C">88</ClassName>★ <MemoNumber memoNumber="Class_D">00</ClassName>★ <MemoNumber memoNumber="Class_E">32</ClassName>★ </MemoNumberList> </IDNo> </IDList> <IDNo IDNo="2">★ <MemoNumberList> <MemoNumber memoNumber="Class_A">42</ClassName>★ <MemoNumber memoNumber="Class_B">90</ClassName>★ <MemoNumber memoNumber="Class_C">101</ClassName>★ <MemoNumber memoNumber="Class_D">978</ClassName>★ <MemoNumber memoNumber="Class_E">21</ClassName>★ </MemoNumberList> </IDNo> </IDList> <IDNo IDNo="3">★ <MemoNumberList> <MemoNumber memoNumber="Class_A">10</ClassName>★ <MemoNumber memoNumber="Class_B">1</ClassName>★ <MemoNumber memoNumber="Class_C">11</ClassName>★ <MemoNumber memoNumber="Class_D">99</ClassName>★ <MemoNumber memoNumber="Class_E">66</ClassName> </MemoNumberList> </IDNo> </IDList> </AmemoWritingLocation> <location>15</location> </AmemoWritingLocationList> </MemoBlock> </MemoBlockList> Javaのソースは以下のとおりです。 import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; public class MemoBlecks { public static void main(String[] args) { try { DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbfactory.newDocumentBuilder(); Document doc = builder.parse(new File("MemoBlock.xml")); Element root = doc.getDocumentElement(); System.out.println("ルート要素のタグ名:" + root.getTagName()); System.out.println("***** 値リスト *****"); System.out.println("要素:memoNumberList"); System.out.println("値:MemoNumberList"); NodeList list = root.getElementsByTagName("MemoNumberList"); for (int i=0; i < list.getLength() ; i++) { Element element = (Element)list.item(i); String MemoNumber = element.getAttribute("memoNumber"); NodeList MemoNumberList = element.getElementsByTagName("MemoNumber"); Element MemoNumberElement = (Element)MemoNumberList.item(0); String MemoNumber = MemoNumberElement.getFirstChild().getNodeValue(); System.out.println("memoNumber="+memoNumber); System.out.println("MemoNumber="+MemoNumber); } } catch (Exception e) { e.printStackTrace(); System.out.println("このウィンドウ上で次の操作を実行してください..."); System.out.println("「右クリック→すべて選択→右クリック→テキストエディタを開き、evaluation.txtとして保存」"); } } } 開発環境は次のとおりです。 OS:WindowsXP HomeEdition SP2 Java:JDK1.6.0_04 Javaに関しては初心者レベルの知識しかありません。そのため、載せたものも少々おかしいですが、どなたかご教授のほどお願い致します。

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

  • ベストアンサー
  • auty
  • ベストアンサー率58% (284/486)
回答No.2

すでに指摘のあるように、xmlファイルが間違って抽出されているようです。 プログラムを拝見しますと、データが2重になっているのにその対処がなされていません。つまり ------------------------------------ 複数の<MemoNumberList>タグに対して 複数の<MemoNumber>タグがあります。 ------------------------------------ これに対して2重のループで処理する必要があります。 次に処理の方法を簡単に挙げてみますので、参考にしてみてください。 -------------------------------------------------------------------- NodeList list = root.getElementsByTagName("MemoNumberList"); for (int i = 0; i < list.getLength(); i++) { Element element = (Element) list.item(i); // String MemoNumber = element.getAttribute("memoNumber"); System.out.println("要素:memoNumberList(" + i + ") ==================="); NodeList MemoNumberList = element .getElementsByTagName("MemoNumber"); for (int j = 0; j < MemoNumberList.getLength(); j++) { Element el = (Element) MemoNumberList.item(j); String memoNumberClass = el.getAttribute("memoNumber"); String memoNumber = el.getFirstChild().getNodeValue(); System.out.println("memoNumberClass=" + memoNumberClass); System.out.println("MemoNumber=" + memoNumber); } } --------------------------------------------------------------------

rootmind
質問者

お礼

回答有り難うございます。 早速プログラムを参考にしながら、修正をかけたところ、XMLファイルから、取り出したいデータを抽出することが出来ました。 > プログラムを拝見しますと、データが2重になっているのにその対処がなされていません。つまり > ------------------------------------ > 複数の<MemoNumberList>タグに対して > 複数の<MemoNumber>タグがあります。 > ------------------------------------ > これに対して2重のループで処理する必要があります。 その通りですね。親タグの中の子タグを読み行くという考えは何となく理解していくつか試してみたものの...このような処理方法があったのですね。 これなら、もしデータの重なりが増えたとしても同じような対処方法を採れると思いましたし。これから、アドバイス頂いたデータを基にいろいろと試してみようかとおもいます。

その他の回答 (1)

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.1

基本的に、そのxmlは不正なので、パーサは扱えません。 <nantoka ...>タグは、</nantoka>で閉じてください。

rootmind
質問者

お礼

回答有り難うございます。 ご指摘の通り、下記のタグは、 <MemoNumber memoNumber="Class_A">53</ClassName> </ClassName>というタグが誤りで、以下の通りが正しかったようです。 <MemoNumber memoNumber="Class_A">53</MemoNumber> また、<IDList>等のタグの開始タグや、挿入すべき所を間違ったタグがあったようでした。 抽出した際、手動で編集してしまったので、編集ミスがあったのではないかと思います。ご指摘を受けたおかけで編集ミスに気付くことが出来ました。是非、気を付けたい項目ですね。

関連するQ&A

専門家に質問してみよう