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

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

ただいまの
回答率

87.37%

XMLのタグ名が複数パターンある場合の検索方法

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,139

score 12

プログラミング、特にXMLに関しては素人のため、タイトルが適当ではないと思われます。すみません。

AmazonマーケットプレイスWebサービス(MWS)を使用し、
ISBNを入力すると返ってくるXMLを解析して、書籍名や著者名、サイズなどの情報を抽出したいと考えております。
XMLから書籍名など一部の情報を抽出するところまでは成功したのですが、
著者名やサイズなどを抽出することができません。

商品名など、抽出できている項目は、タグのパターンが一種類です。
(商品名→<ns2:title>、出版社<ns2:Publisher>)

一方、抽出できない項目は、タグのパターンが複数種類あり、どのように指定すれば良いのかわかりません。
(著者名→<ns2:Creator Role="著"><ns2:Creator Role="翻訳"><ns2:Creator Role="Unknown">など、
サイズ→<ns2:Height Units="inches"><ns2:Height Units="pixels">など)
各項目ごとに、""の中以外は同じ文字列です。

こちらのAPIは同時に5つのISBNを送り、情報を取得できます。
そのため、5つのレスポンスすべてに<ns2:Creator Role="翻訳">のタグが含まれていれば問題ありませんが、
1つでも含まれていなかった場合、NullPointerExceptionが出てしまいます。
タグにどのようなパターンがあるかは不明ですので、
例外処理を行って全てのパターンを指定するという方法は、できれば避けたいです。
共通する文字列で部分一致などは可能でしょうか。
また、著者や翻訳が複数いる場合には、すべてを抽出したいです。

お力をかしていただけないでしょうか。
不足情報などがありましたら補足致しますので、ご指摘くださいませ。

【実行結果】
下記JAVAコードではエラーは出ず、商品名、ASIN、分類、出版社が下記のように返ってきます。

NATURE'S ROBOTS―それはタンパク質研究の壮大な歴史,4860434730,単行本(ソフトカバー),エヌ・ティー・エス

指定しているISBNは1つです。
著者・サイズは記載方法がわからず、いろいろ試しましたがNullPointerExceptionが返ってきてしまいます。
ISBNの受け渡しはメインメソッドで行っています。不要かと思い省いていますが、必要でしたらメインメソッドも記載致します。
例外処理は行っていませんが、後に記載するつもりです。

    public static void ExportXml() throws ParserConfigurationException, SAXException, IOException { //Xmlのノードを分析
        String responseXml = GetMatchingProductForIdSample.responseXml;

        InputSource inputSource = new InputSource(new StringReader(responseXml)); //String型をInputSource型に変換
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(inputSource);

        NodeList nodesTitle = doc.getElementsByTagName("ns2:Title"); //商品名
        NodeList nodesAsin = doc.getElementsByTagName("ASIN"); //ASIN
        NodeList nodesCreator = doc.getElementsByTagName("ns2:Creator Role=\".*\""); //著者、記載方法がわからず
        NodeList nodesBinding = doc.getElementsByTagName("ns2:Binding"); //分類
        NodeList nodesPublisher = doc.getElementsByTagName("ns2:Publisher"); //出版社
        NodeList nodesHeight = doc.getElementsByTagName("ns2:Height Units=\"inches\""); //サイズ、記載方法がわからず

        for(int i=0; i<nodesTitle.getLength();i++)
        {
            System.out.println(nodesTitle.item(i).getTextContent()+","+nodesAsin.item(i).getTextContent()+","+nodesBinding.item(i).getTextContent()+","+nodesPublisher.item(i).getTextContent());
        }
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01"><GetMatchingProductForIdResult Id="9784860434731" IdType="ISBN" status="Success"><Products><Product><Identifiers><MarketplaceASIN><MarketplaceId>A1VC38T7YXB528</MarketplaceId><ASIN>4860434730</ASIN></MarketplaceASIN></Identifiers><AttributeSets><ns2:ItemAttributes xml:lang="ja-JP" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"><ns2:Binding>単行本(ソフトカバー)</ns2:Binding><ns2:Creator Role="著">Charles Tanford</ns2:Creator><ns2:Creator Role="著">Jacqueline Reynolds</ns2:Creator><ns2:Creator Role="翻訳">浜窪 隆雄</ns2:Creator><ns2:Creator Role="翻訳">他5名</ns2:Creator><ns2:ItemDimensions><ns2:Height Units="inches">0.6692913379</ns2:Height><ns2:Length Units="inches">8.267716527</ns2:Length><ns2:Width Units="inches">5.8267716476</ns2:Width></ns2:ItemDimensions><ns2:IsAdultProduct>false</ns2:IsAdultProduct><ns2:Label>エヌ・ティー・エス</ns2:Label><ns2:Languages><ns2:Language><ns2:Name>japanese</ns2:Name><ns2:Type>Published</ns2:Type></ns2:Language></ns2:Languages><ns2:ListPrice><ns2:Amount>3024.00</ns2:Amount><ns2:CurrencyCode>JPY</ns2:CurrencyCode></ns2:ListPrice><ns2:Manufacturer>エヌ・ティー・エス</ns2:Manufacturer><ns2:NumberOfPages>342</ns2:NumberOfPages><ns2:PackageDimensions><ns2:Height Units="inches">0.8661417314</ns2:Height><ns2:Length Units="inches">8.4251968418</ns2:Length><ns2:Width Units="inches">5.9055118050</ns2:Width><ns2:Weight Units="pounds">1.0582188576</ns2:Weight></ns2:PackageDimensions><ns2:ProductGroup>Book</ns2:ProductGroup><ns2:ProductTypeName>ABIS_BOOK</ns2:ProductTypeName><ns2:PublicationDate>2018-03-30</ns2:PublicationDate><ns2:Publisher>エヌ・ティー・エス</ns2:Publisher><ns2:SmallImage><ns2:URL>http://ecx.images-amazon.com/images/I/61b3ceNG8jL._SL75_.jpg</ns2:URL><ns2:Height Units="pixels">75</ns2:Height><ns2:Width Units="pixels">53</ns2:Width></ns2:SmallImage><ns2:Studio>エヌ・ティー・エス</ns2:Studio><ns2:Title>NATURE'S ROBOTS―それはタンパク質研究の壮大な歴史</ns2:Title></ns2:ItemAttributes></AttributeSets><Relationships></Relationships><SalesRankings><SalesRank><ProductCategoryId>book_display_on_website</ProductCategoryId><Rank>361226</Rank></SalesRank><SalesRank><ProductCategoryId>500796</ProductCategoryId><Rank>74</Rank></SalesRank><SalesRank><ProductCategoryId>492162</ProductCategoryId><Rank>4523</Rank></SalesRank></SalesRankings></Product></Products></GetMatchingProductForIdResult><ResponseMetadata><RequestId>7efe54c2-8a52-4b16-9cef-466971ff6aa6</RequestId></ResponseMetadata></GetMatchingProductForIdResponse>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

タグ(要素)と属性がごっちゃになっているようです。
例えば <ns2:Creator Role="著"> の場合、以下のようになります。
(正確には名前空間(namespace)の説明も必要ですが、今回は不要なので省略)

  • タグ名(要素名): ns2:Creator
  • 属性名: Role
  • 属性値: 

ソースコードを見ると doc.getElementsByTagName("ns2:Creator Role=\".*\"") と書かれていますが、引数に指定できるのはタグ名(要素名)だけです。なので、doc.getElementsByTagName("ns2:Creator")のようにする必要があります。

ではRoleはどのように取得するのかというと、 Element#getAttribute() メソッドを使う必要があります。また、<ns2:Creator ...> 〜 </ns2:Creator> で囲まれたテキストは Element#getTextContent() メソッドを使って取得します。

最終的には以下のようにすれば取得できます(Creatorのみ対応)。

// 省略
NodeList nodesCreator = doc.getElementsByTagName("ns2:Creator");
// 省略

for (int i = 0; i < nodesTitle.getLength(); i++) {
    // 省略

    for (int j = 0; j < nodesCreator.getLength(); j++) {
        Element creator = (Element) nodesCreator.item(j);
        String role = creator.getAttribute("Role");
        String creatorName = creator.getTextContent();
        System.out.println(role + ":" + creatorName);
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/08/30 12:56

    XMLは初めてだったのでよく理解できていませんでしたが、
    大変わかりやすく教えていただき、ありがとうございました!
    おかげさまでやりかたかったように抽出することができました!
    またお力を貸して頂ければ嬉しいです。

    キャンセル

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

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る