質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

2回答

2575閲覧

getElementsByTagNameの正しい使いかた

onoko

総合スコア40

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2021/10/10 12:46

編集2021/10/10 14:28

XML初心者です。javaプログラムで階層を降りてXMLデータを取得するよう努めたのですがうまくいきませんでした。そこでノードツリーを辿るのではなく、getElementsByTagName()を使って、指定の要素名の要素の一覧を取得しそこからデータを得ようとしています。しかしコンソールに対応に困るようなエラーが出て立ちどまっています。

エラー:=java.lang.ClassCastException: class com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl cannot be cast to class org.w3c.dom.Node (com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl and org.w3c.dom.Node are in module java.xml of loader 'bootstrap')

NodeListも org.w3c.dom  のものをimportしてあると思うのですが影響してないように見えます。
データを得るためこのエラーを回避する方法をご教授ください。

Java

1package model; 2 3 4import java.net.URL; 5 6import javax.net.ssl.HttpsURLConnection; 7import javax.xml.parsers.DocumentBuilder; 8import javax.xml.parsers.DocumentBuilderFactory; 9 10import org.w3c.dom.Element; 11import org.w3c.dom.Node; 12import org.w3c.dom.NodeList; 13 14 15public class Retrieve { 16 17 18 19 public String[] retrieve(String ISBN){ 20 21 String [] data = new String[6]; 22 try { 23 URL url = new URL("https://iss.ndl.go.jp/api/sru?operation=searchRetrieve&query=isbn%3d%22"+ISBN+"%22"); 24 HttpsURLConnection https = (HttpsURLConnection)url.openConnection(); 25 https.setRequestMethod("GET"); 26 https.connect(); 27 28 DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); 29 DocumentBuilder builder = dbfactory.newDocumentBuilder(); 30 Element searchRetrieveResponseNode = builder.parse(https.getInputStream()).getDocumentElement(); 31 System.out.println("searchRetrieveResponseNode.getTextContent()="+searchRetrieveResponseNode.getTextContent()); 32 33 data[5] = ISBN; 34 System.out.println("try0.01"); 35 NodeList titles = searchRetrieveResponseNode.getElementsByTagName("dc:title"); 36 System.out.println("try0.10"); 37 System.out.println("titles="+titles); 38 System.out.println("titles.getTextContent()="+((Node)titles).getTextContent()); 39 System.out.println("try0.11"); 40 data[0] = ((Node)titles).getTextContent(); 41 42https.disconnect(); 43 } 44 catch(Exception e) { 45 System.out.println("catch"); 46 System.out.println("e="+e); 47 } 48 return data; 49 } 50}

XML

11.2 2 1 3 0 4 5<facets> 6 <lst name="REPOSITORY_NO"> 7 <int name="R100000001">1</int> 8 <int name="R100000002">1</int> 9 </lst> 10 <lst name="NDC"> 11 </lst> 12 <lst name="ISSUED_DATE"> 13 <int name="2015">1</int> 14 </lst> 15 <lst name="LIBRARY"> 16 <int name="さいたま市立中央図書館">1</int> 17 <int name="国立国会図書館">1</int> 18 <int name="堺市立中央図書館">1</int> 19 <int name="大阪市立図書館">1</int> 20 <int name="大阪府立中央図書館">1</int> 21 <int name="奈良県立図書情報館">1</int> 22 <int name="山口県立山口図書館">1</int> 23 <int name="山形県立図書館">1</int> 24 <int name="川崎市立図書館">1</int> 25 <int name="新潟県立図書館">1</int> 26 <int name="札幌市中央図書館">1</int> 27 <int name="栃木県立図書館">1</int> 28 <int name="沖縄県立図書館">1</int> 29 <int name="滋賀県立図書館">1</int> 30 <int name="県立長野図書館">1</int> 31 <int name="福岡市総合図書館">1</int> 32 <int name="群馬県立図書館">1</int> 33 <int name="若狭図書学習センター">1</int> 34 <int name="長崎県立長崎図書館">1</int> 35 <int name="香川県立図書館">1</int> 36 <int name="鳥取県立図書館">1</int> 37 </lst> 38</facets> 39 40 41 42 info:srw/schema/1/dc-v1.1 43 string 44 45<srw_dc:dc xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:srw_dc="info:srw/schema/1/dc-v1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="info:srw/schema/1/dc-v1.1 http://www.loc.gov/standards/sru/dc-schema.xsd"> 46 <dc:title>できるWindows 10</dc:title> 47 <dc:creator>法林岳之, 一ケ谷兼乃, 清水理史, できるシリーズ編集部 著</dc:creator> 48 <dc:description>Home/Pro/Enterprise対応</dc:description> 49 <dc:description>索引あり</dc:description> 50 <dc:publisher>インプレス</dc:publisher> 51 <dc:language>jpn</dc:language> 52</srw_dc:dc> 53 54 1 55 56 57

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cx20

2021/10/10 13:29

質問の趣旨と違いますが、メソッド名は下記が正しいかと思います。 誤)getElementByTagName 正)getElementsByTagName
onoko

2021/10/10 13:49

その通りでした。
cx20

2021/10/10 14:08

質問のタイトルは変更して頂いた方が良いかと思います。 ちなみに、サンプルコード(main()関数を追加するなど多少修正して)をローカル環境で試してみましたが、エラー再現できませんでした。 可能であればエラーが再現するコードを提示頂けると回答しやすいかと思います。
guest

回答2

0

ベストアンサー

繁雑な属性を持つXML要素を起点としてgetFirstChild()の読むもの
はこちらから繋がっているようですので、 cx20 さんご提示の xml 等こちらの情報を元に XPath を使って以下のコードを作成してみました。

java

1import java.io.ByteArrayInputStream; 2import java.io.IOException; 3import java.net.URL; 4import java.util.ArrayList; 5import java.util.List; 6 7import javax.net.ssl.HttpsURLConnection; 8import javax.xml.parsers.*; 9import javax.xml.xpath.*; 10 11import org.w3c.dom.Document; 12import org.w3c.dom.NodeList; 13import org.xml.sax.SAXException; 14 15public class Q363771 { 16 public static void main(String[] args) throws Exception { 17 List<Book> bookList = getBookList("9784295010517"); 18 for(Book b: bookList) System.out.println(b); //確認 19 } 20 21 static List<Book> getBookList(String isbn) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException { 22 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 23 //factory.setNamespaceAware(true); 24 DocumentBuilder builder = factory.newDocumentBuilder(); 25 26 Document document = getDocument(isbn, builder); 27 28 XPath xpath = XPathFactory.newInstance().newXPath(); 29 30 XPathExpression recordDataExpr = xpath.compile("//record/recordData/text()"); 31 NodeList recordDataList = (NodeList)recordDataExpr.evaluate(document, XPathConstants.NODESET); 32 33 List<Book> bookList = new ArrayList<>(); 34 35 XPathExpression titleExpr = xpath.compile("//title/text()"); 36 XPathExpression creatorExpr = xpath.compile("//creator/text()"); 37 XPathExpression publisherExpr = xpath.compile("//publisher/text()"); 38 39 for(int i=0; i<recordDataList.getLength(); i++) { 40 String data = recordDataList.item(i).getTextContent(); 41 Document datadoc = builder.parse(new ByteArrayInputStream(data.getBytes("UTF-8"))); 42 43 String title = (String)titleExpr.evaluate(datadoc, XPathConstants.STRING); 44 String creator = (String)creatorExpr.evaluate(datadoc, XPathConstants.STRING); 45 String publisher = (String)publisherExpr.evaluate(datadoc, XPathConstants.STRING); 46 bookList.add(new Book(title, creator, publisher)); 47 } 48 49 return bookList; 50 } 51 52 static Document getDocument(String isbn, DocumentBuilder builder) throws IOException, SAXException { 53 String operation = "searchRetrieve"; 54 String query = URLEncoder.encode("isbn=\""+isbn+"\"", "UTF-8"); 55 URL url = new URL("https://iss.ndl.go.jp/api/sru?operation="+operation+"&query="+query); 56 HttpsURLConnection https = (HttpsURLConnection)url.openConnection(); 57 https.setRequestMethod("GET"); 58 https.connect(); 59 try { 60 return builder.parse(https.getInputStream()); 61 } finally { 62 https.disconnect(); 63 } 64 } 65 66 static class Book { 67 final String title, creator, publisher; 68 Book(String title, String creator, String publisher) { 69 this.title = title; 70 this.creator = creator; 71 this.publisher = publisher; 72 } 73 @Override 74 public String toString() { 75 return new StringBuilder("Book") 76 .append("[title='").append(title).append("'") 77 .append(",creator='").append(creator).append("'") 78 .append(",publisher='").append(publisher).append("'") 79 .append("]").toString(); 80 } 81 } 82}

実行結果

plain

1Book[title='できるWindows10',creator='法林岳之 [ほか] 著',publisher='インプレス'] 2Book[title='できるWindows 10',creator='法林岳之, 一ケ谷兼乃, 清水理史, できるシリーズ編集部 著',publisher='インプレス']

投稿2021/10/11 11:50

編集2021/10/12 10:49
jimbe

総合スコア12659

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cx20

2021/10/11 15:04

回答ありがとうございます。Java にそれほど詳しくないので参考になります。 もし差支えなければ2点程教えて頂けますか? ・Java のバージョンは11以上が必要でしょうか?(Java 8 だとコンパイルエラーになった為) ・自分の環境だと getBytes("UTF-8") としないと実行時エラー「 1バイトのUTF-8シーケンスのバ イト1が無効です。」になりました。実行時エラーを回避するにはどうすれば良いでしょうか?
jimbe

2021/10/11 16:00 編集

コンパイルエラーは DocumentBuilderFactory.newDefaultInstance(); でしょうか。 newDefaultInstance() メソッドは java9からのようですね。newInstance() でも動作します。が、ドキュメント上は newInstance() はプロパティファイルを参照するようだったので、何かの拍子にプロパティファイルが存在するとその内容によっては動作が変わるかもしれません。 getBytes() はパラメータを指定しないと実行環境に基づいて動作しますので、 "UTF-8" を指定したほうが良いですね。xml の charset を用いようかと思ったのですが、手を抜きました ^^;
cx20

2021/10/11 16:01

ありがとうございます。 ・newInstance() で、Java 8 でも動作し ・java -Dfile.encoding=UTF-8 Q363771 とすることで、実行時のエンコードが指定できる ことを確認しました。
jimbe

2021/10/12 10:50

ご指摘ありがとうございました。
guest

0

DeepNodeListImpl cannot be cast to class org.w3c.dom.Node
DeepNodeListImplをクラスをorg.w3c.dom.Nodeにキャストすることはできません

エラーメッセージから推察すると、ここが怪しい気がします。

System.out.println("titles.getTextContent()="+((Node)titles).getTextContent());

NodeList を Node にキャストしているのがまずそうですね。。

あと、そもそも「dc:title」が取得できてないですね。。

NodeList titles = searchRetrieveResponseNode.getElementsByTagName("dc:title");

XML のデータを確認してみましたが、データが入れ子構造になっており、recordData の中に内包された XML が実体参照で格納されているようでした。
ですので、一旦、recordData の中を取り出した後、再度、XML を parse する必要がありそうです。

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/"> 3 <version>1.2</version> 4 <numberOfRecords>2</numberOfRecords> 5 <nextRecordPosition>0</nextRecordPosition> 6 <extraResponseData> 7&lt;facets&gt; 8 &lt;lst name=&quot;REPOSITORY_NO&quot;&gt; 9 &lt;int name=&quot;R100000001&quot;&gt;1&lt;/int&gt; 10 &lt;int name=&quot;R100000002&quot;&gt;1&lt;/int&gt; 11 &lt;int name=&quot;R100000096&quot;&gt;1&lt;/int&gt; 12 &lt;/lst&gt; 13 &lt;lst name=&quot;NDC&quot;&gt; 14 &lt;int name=&quot;0&quot;&gt;2&lt;/int&gt; 15 &lt;/lst&gt; 16 &lt;lst name=&quot;ISSUED_DATE&quot;&gt; 17 &lt;int name=&quot;2016&quot;&gt;2&lt;/int&gt; 18 &lt;/lst&gt; 19 &lt;lst name=&quot;LIBRARY&quot;&gt; 20 &lt;int name=&quot;さいたま市立中央図書館&quot;&gt;1&lt;/int&gt; 21 &lt;int name=&quot;千葉市中央図書館&quot;&gt;1&lt;/int&gt; 22 &lt;int name=&quot;国立国会図書館&quot;&gt;1&lt;/int&gt; 23 &lt;int name=&quot;堺市立中央図書館&quot;&gt;1&lt;/int&gt; 24 &lt;int name=&quot;大阪市立図書館&quot;&gt;1&lt;/int&gt; 25 &lt;int name=&quot;奈良県立図書情報館&quot;&gt;1&lt;/int&gt; 26 &lt;int name=&quot;島根県立図書館&quot;&gt;1&lt;/int&gt; 27 &lt;int name=&quot;川崎市立図書館&quot;&gt;1&lt;/int&gt; 28 &lt;int name=&quot;沖縄県立図書館&quot;&gt;1&lt;/int&gt; 29 &lt;int name=&quot;滋賀県立図書館&quot;&gt;1&lt;/int&gt; 30 &lt;int name=&quot;相模原市立図書館&quot;&gt;1&lt;/int&gt; 31 &lt;int name=&quot;福岡県立図書館&quot;&gt;1&lt;/int&gt; 32 &lt;int name=&quot;香川県立図書館&quot;&gt;1&lt;/int&gt; 33 &lt;/lst&gt; 34&lt;/facets&gt; 35 </extraResponseData> 36 <records> 37 <record> 38 <recordSchema>info:srw/schema/1/dc-v1.1</recordSchema> 39 <recordPacking>string</recordPacking> 40 <recordData> 41&lt;srw_dc:dc xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:srw_dc=&quot;info:srw/schema/1/dc-v1.1&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;info:srw/schema/1/dc-v1.1 http://www.loc.gov/standards/sru/dc-schema.xsd&quot;&gt; 42 &lt;dc:title&gt;できるWindows10&lt;/dc:title&gt; 43 &lt;dc:creator&gt;法林岳之 [ほか] 著&lt;/dc:creator&gt; 44 &lt;dc:subject&gt;オペレーティングシステム&lt;/dc:subject&gt; 45 &lt;dc:description&gt;Home/Pro/Enterprise対応&lt;/dc:description&gt; 46 &lt;dc:description&gt;その他の著者: 一ケ谷兼乃, 清水理史, できるシリーズ編集部&lt;/dc:description&gt; 47 &lt;dc:publisher&gt;インプレス&lt;/dc:publisher&gt; 48 &lt;dc:language&gt;jpn&lt;/dc:language&gt; 49&lt;/srw_dc:dc&gt; 50 </recordData> 51 <recordPosition>1</recordPosition> 52 </record> 53 <record> 54 <recordSchema>info:srw/schema/1/dc-v1.1</recordSchema> 55 <recordPacking>string</recordPacking> 56 <recordData> 57&lt;srw_dc:dc xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot; xmlns:srw_dc=&quot;info:srw/schema/1/dc-v1.1&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;info:srw/schema/1/dc-v1.1 http://www.loc.gov/standards/sru/dc-schema.xsd&quot;&gt; 58 &lt;dc:title&gt;できるWindows 10&lt;/dc:title&gt; 59 &lt;dc:creator&gt;法林岳之, 一ケ谷兼乃, 清水理史, できるシリーズ編集部 著&lt;/dc:creator&gt; 60 &lt;dc:subject&gt;オペレーティングシステム&lt;/dc:subject&gt; 61 &lt;dc:description&gt;Home/Pro/Enterprise対応&lt;/dc:description&gt; 62 &lt;dc:description&gt;索引あり&lt;/dc:description&gt; 63 &lt;dc:publisher&gt;インプレス&lt;/dc:publisher&gt; 64 &lt;dc:language&gt;jpn&lt;/dc:language&gt; 65&lt;/srw_dc:dc&gt; 66 </recordData> 67 <recordPosition>2</recordPosition> 68 </record> 69 </records> 70</searchRetrieveResponse>

投稿2021/10/10 14:31

編集2021/10/10 16:46
cx20

総合スコア4633

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

onoko

2021/10/10 14:58

<要素>テキスト</要素>が一件だけのNodeListなので、Nodeにキャストできそうな気がしたのですが誤りでしたか。しかしNodeList()に続けると、"getTextContent()は、型NodeListeで未定義です。"とのポップアップが出て文法エラーになってしまい使えません。規則書のString NodeValue = node.getNodeValue(); (j実際はgetTextContent()を使っていますがgetNodeValue()も同じ表示なことを確認)に合わないエラーチェックで困ったもんだと思っているのです。
cx20

2021/10/10 15:06

for (int i = 0; i < titles.getLength(); i++ ) {  Element title = (Element) titles.item(i);  String content = title.getTextContent(); }
onoko

2021/10/10 15:53

親切なご回答ありがたいことです。 そうなのですが、titleの中味の<dc:title><できるWindows 10</dc:title>は、テキストを含むだけで子要素を持っておらず、子要素を表す.item(0)を付けると、もともとないので、NullPointerExceptionを起こすのです。かといって.item(0)をとるとe=java.lang.ClassCastException: class com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl cannot be cast to class org.w3c.dom.Element (com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl and org.w3c.dom.Element are in module java.xml of loader 'bootstrap')のキャストエラーが発生します。一段の工夫が必要です。
cx20

2021/10/10 16:30

少し調べてみましたが、getElementsByTagName("dc:title") で、そもそも値が取れてないですね。 XMLのデータ構造について回答欄を参照下さい。
onoko

2021/10/10 16:41

「 データが入れ子構造になっており、recordData の中に内包された XML が実体参照で格納されているようでした。 ですので、一旦、recordData の中を取り出した後、再度、XML を parse する必要がありそうです。」 以上のお言葉ありがとうございます。私の全く知らない範囲の知識でした。どうもこの部分に来るとうまくいかないと思った。この部分について新たに勉強して使いこなせるようになってからまたご返事差し上げます。
cx20

2021/10/10 16:43

下記説明によると検索 API としては3つのプロトコル(SRU / OpenSearch / OpenURL)が提供されているようです。現在使用しているのは、SRU ですが OpenSearch の方が扱いやすい気がしました。 ■ API仕様の概要 « 国立国会図書館サーチについて https://iss.ndl.go.jp/information/api/riyou/
onoko

2021/10/10 17:16

いまOpenSearchを拝見しましたが、こっちのほうが平明な構造で属性に頼ることも少なく情報量も多いのでいい点が豊富です。ただRSSというXMLの一形式を用いているところが難しくなければいいのですが。検討してみようと思います。
cx20

2021/10/11 16:07

何をしたいかにもよると思いますが RSS は悪くない選択肢ではないかと思います(主観です)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問