• ベストアンサー

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

  • ?__mode=rssのRSSデータからトラックバックをしたトラックバック先のURLを取得するプログラムの改正

    import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; public class GetTBlink { public static void main(String[] args) { try { String url = "http://app.blog.livedoor.jp/takapon_ceo/tb.cgi/50030092?__mode=rss"; DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbfactory.newDocumentBuilder(); Document doc = builder.parse(url); Element root = doc.getDocumentElement(); NodeList list0 = root.getElementsByTagName("error"); Element element0 = (Element)list0.item(0); NodeList list1 = root.getElementsByTagName("rss"); Element element = (Element)list1.item(0); NodeList list2 = root.getElementsByTagName("channel"); Element element1 = (Element)list2.item(0); NodeList list3 = element1.getElementsByTagName("item"); for (int i=0; i < list3.getLength() ; i++) { Element element2 = (Element)list3.item(i); NodeList linkList = element2.getElementsByTagName("link"); Element linkElement = (Element)linkList.item(0); String link = linkElement.getFirstChild().getNodeValue(); System.out.println("リンク:" + link ); } } catch (Exception e) { e.printStackTrace(); } } } 以上のプログラムを次のように改正したいです。 pingurl = http://app.blog.livedoor.jp/takapon_ceo/tb.cgi/50030092として、 pingurlの後ろに ?__mode=rssを付加させるようにして String url を指定したい (String url = (pingurl)?__mode=rss のようなイメージ)  よろしくお願いします。

    • ベストアンサー
    • 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
  • JavaによるXMLの中身の取り出し

    以下のindex.xmlのようなXML文書があるとして、Javaプログラム で<Title></Title>の中身を抜き出したいのですが、うまく取り 出せません。 【index.xml】 <?xml version='1.0' encoding='UTF-8' ?> <?xml-stylesheet type="text/xsl" href="../../../_sys/style.xsl"?> <RDF xmlns:r="○○" xmlns:d="○○" xmlns:s="○○" xmlns="○○"> <ExternalPage about="http://www.pref.iwate.jp/~hp0920/"> <d:Title><s:char code="39">'</s:char>99岩手総体</d:Title> </ExternalPage> </RDF> 【ソース】 public class Example { public static void main(String[] args) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(new File("index.xml")); Element root = doc.getDocumentElement(); NodeList ExternalPageLst = root.getElementsByTagName("ExternalPage"); for (int j=0; j < ExternalPageLst.getLength() ; j++) { Element ExternalPageEle = (Element)ExternalPageLst.item(j); NodeList TitleLst = ExternalPageEle.getElementsByTagName("d:Title"); for (int k=0; k < TitleLst.getLength() ; k++) { Element TitleEle = (Element)TitleLst.item(k); NodeList CharLst = ExternalPageEle.getElementsByTagName("s:char"); Element CharEle = (Element)CharLst.item(0); String Char = CharEle.getFirstChild().getNodeValue(); String Title = TitleEle.getFirstChild().getNodeValue(); System.out.println(Title); } } catch (Exception e) { e.printStackTrace(); } } } 【実行結果】 null 以上、宜しくお願いします。

    • ベストアンサー
    • Java
  • JavaでXMLといったら何を使いますか?

    JavaでXMLファイルを取り扱うときには、DOM, SAX, xerces, relaxer, XMLSchema, XPathといったキーワードが出てきますが、とりあえずXMLファイルを読めればいい、というときはどのライブラリを使うのがいいのでしょうか? 利用目的としては、単純なXMLからデータを読み込んで、それをVelocityテンプレートとマージしてファイルに保存することを考えています。 例 <javafile>  <name>Foo.java</name>  <class>   <modifier>public</modifier>   <name>Foo</name>   <method>    <modifier>public</modifier>    <modifier>static</modifier>    <type>void</type>    <name>main</name>    <arg>     <type>String[]</type>     <name>args</name>    </arg>    <body>     System.out.println("Hello");    </body>   </method>  </class> </javafile> から public class Foo{  public static void main(String[] args){   System.out.println("Hello");  } } を作る感じです。

    • ベストアンサー
    • Java
  • java

    次のコード中の括弧内で下に示す11通りの各コードを実行した場合の実行画面を正確に答えよ。 class A{ public void func1(){System.out.println("A1");} public void func2(){System.out.println("A2");} } class B extends A{ public void func1(){System.out.println("B");} } class C{ public int x=0, y=1; } class D extends C{ public int x=2; public void func1(int x){System.out.println(x);} public void func2(int x){System.out.println(this.x);} public void func3(int x){System.out.println(super.x);} public void func4(int x){System.out.println(this.y);} public void func5(int x){System.out.println(super.y);} } class E{ public void func1(int n){ try{ System.out.println("E1"); int[] ary=new int[n]; System.out.println("E2"); }catch(NegativeArraySizeException e){ System.out.println("E3"); }finally{ System.out.println("E4"); } } } (1) A a=new A(); a.func1(); (2) A a=new B(); a.func1(); (3) B b=new B(); b.func1(); (4) B b=new B(); b.func2(); (5) D d=new D(); d.func1(3); (6) D d=new D(); d.func2(3); (7) D d=new D(); d.func3(3); (8) D d=new D(); d.func4(3); (9) D d=new D(); d.func5(3); (10) E e=new E(); e.func1(5); (11) E e=new E(); e.func1(-2); (1) A1 (2)B (3)B (4) A2 (5) 3 (6) 2 (7) 0 (8) 1 (9) 1 (10) E1E2E4(11) E1E3E4 と答えになるんですがなぜこうなるのかわかりません。教えてください

    • ベストアンサー
    • Java
  • XMLの処理について

    javaでxmlをsoapで投げる処理をしています。 <クライアント> DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dbf.newDocumentBuilder(); Document doc = builder.parse( new File( "test.xml" ) ); Element elm = doc.getDocumentElement(); result = WebService( elm ); <サーバ> public Object WebService( Element elm ) { return 'elmを処理した結果'; } このクライアントの処理をperlで行いたいのですが、可能でしょうか?  : $service = SOAP::Lite->Service( "xxx.wdsl" ); open( XML, "test.xml" ); @xml = <XML>; ?? ここの処理はどうすれば ?? result = $service.WebService( @xml );  :

  • XMLファイルの読み方

    以下の様なXMLファイルがあるとします。 "groupノード(?)のアトリビュートであるgrpIDとnumStdGrpの値を取得したいです。 JavaでDOMパーサーを使うことに限定します。 <?xml version="1.0" encoding="UTF-8"?> <dataHeader <numStudent>150</numStudent> <dataMain <band name="B1"> <group grpID="1" numStdGrp="15"/> </band> <band name="B2"> <group grpID="2" numStdGrp="10"/> </band> </dataMain> </dataHeader> 自分では試して見たのは以下まで。 File fXmlFile = new File("C:\XMLファイル名"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(fXmlFile); doc.getDocumentElement().normalize(); (1)numStudentとdataMainノードまでは簡単: 例) NodeList nListDM = doc.getElementsByTagName("dataMain"); 上記からnListDM.item(0)してノード取得できて、getNodeName()で名前表示する。 (2)bandノード(?)もgetElementsByTagNameで取れます。 NodeList nListBand = doc.getElementsByTagName("band"); このノードリストの長さは2です。それぞれ、アトリビュート「name」の値(B1, B2)は以下の様にして取れます。 Node nNodeBand = nListBand.item(0); Element bElement = (Element) nNodeBand; して、bElement.getAttribute("name")。 問題はこの以降。 初めに書きましたように、 groupノード(?)のアトリビュートであるgrpIDとnumStdGrpの値どうやって取得するのでしょうか? getElementsByTagName(group)はだめです。どのbandのgroupか、区別できないので。 Java+XMLに詳しい方、教えてください。 よろしくお願いします。

    • ベストアンサー
    • Java
  • Javaのコンストラクタについて教えてください

    Javaを勉強している初心者です。 次のようなプログラムがあります。 このプログラムでclass aおよびclass bのデフォルトコンストラクタ a() {}とb() {}をコーディングしていないとコンパイルエラーになります。 b() {}についてはclass bのパラメータのあるコンストラクタb(String s)がサブクラスclass cから明示的に呼ばれていないのでデフォルトコンストラクタb() {}をコーディングしないとエラーになる…と考えればよいのでしょうか。 それでは、a() {}はなぜ必要なのでしょうか。 どなたか教えてください。 class a { a() {} a(String s) { System.out.println("In a's constructor..."); System.out.println(s); } } class b extends a { b() {} b(String s) { super(s); System.out.println("In b's constructor..."); System.out.println(s); } } class c extends b { c(String s) { System.out.println("In c's constructor..."); System.out.println(s); } public void some() { System.out.println("something..."); } } public class appJ01 { public static void main(String args[]) { c obj = new c("Hello from 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
  • JavaでのXMLパーサの使用について

    javaでパーサを使ってDOMツリーを作成したいのですが、パーサインスタンスが作成できずにエラーがでてしまいます。ちなみにコンパイルは通ります。 以下にソースとエラー内容を記述しますので、もしよろしかったらどなたか教えて下さい。 import java.io.*; import com.ibm.xml.parsers.*; import org.xml.sax.*; import org.w3c.dom.*; public static void main(String[] args){ try{      //XML文書作成 String xml = "<sample>Hello Java World</sample>"; //DOMパーサ作成 DOMParser parser = new DOMParser(); //入力ストリーム作成      StringReader sr = new StringReader(xml); InputSource is = new InputSource(sr); //パースする parser.parse(is); //ドキュメントを得る Document doc = parser.getDocument(); //トップレベル要素を得る Element el = doc.getDocumentElement(); System.out.println("Top Level Element: " + el.getTagName()); } catch(Exception e){ e.printStackTrace(); } } エラー内容: java.lang.NoClassDefFoundError: com.ibm.xml.parsers.DOMParser java.lang.Throwable(java.lang.String) java.lang.Error(java.lang.String) java.lang.LinkageError(java.lang.String) java.lang.NoClassDefFoundError(java.lang.String) void pkxml.dom.PsDomBean.makedom() void pkxml.dom.PsDomBean.makedom() void pkxmlsutabu.Sutabu.main(java.lang.String [])