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

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

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

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

Java

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

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

5952閲覧

JavaでxmlからSAXで取得した値をHashMapに格納したいです。

KAONAGA9

総合スコア5

XML

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

Java

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

Webサイト

一つのドメイン上に存在するWebページの集合体をWebサイトと呼びます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

1クリップ

投稿2020/02/29 12:28

編集2020/02/29 14:12

前提・実現したいこと

Javaでxmlを読み込んで内容をDBに保存する処理を作っています。
SAXでxmlを解析してHashMapに値格納したいのですが、
値を取り出そうとするとnullになってしまいます。

発生している問題・エラーメッセージ

NullPointerException

該当のソースコード

Java

1 2import java.io.ByteArrayInputStream; 3 4 5import java.io.InputStream; 6import java.util.HashMap; 7import java.util.Map; 8 9import javax.xml.parsers.SAXParser; 10import javax.xml.parsers.SAXParserFactory; 11 12import org.xml.sax.Attributes; 13import org.xml.sax.SAXException; 14import org.xml.sax.helpers.DefaultHandler; 15 16public class SAXSample extends DefaultHandler { 17 boolean boolItem = false; 18 boolean boolASIN = false; 19 boolean boolAmount = false; 20 boolean boolOLC = false; 21 boolean boolSR = false; 22 boolean boolRank = false; 23 boolean boolLandedPrice = false; 24 boolean boolCategoryId = false; 25 String asinKey = null; 26 27 //戻り値用、多次元マップ 28 Map<String, Map<String,String>> map = new HashMap<String, Map<String,String>>(); 29 Map<String, String> submap = new HashMap<String, String>(); 30 31 public void startDocument(){ 32// System.out.println("Start Document"); 33 } 34 35 public void startElement(String uri, String localName,String qName, 36 Attributes attributes) throws SAXException { 37 if (qName.equalsIgnoreCase("ASIN")) { 38 boolASIN = true; 39 } 40 if (qName.equalsIgnoreCase("Amount")){ 41 boolAmount = true; 42 } 43 if (qName.equalsIgnoreCase("OfferListingCount")) { 44 if ("New".equals(attributes.getValue(0))) { 45 boolOLC = true; 46 } 47 } 48 if (qName.equalsIgnoreCase("Rank")) { 49 boolRank = true; 50 } 51 if (qName.equalsIgnoreCase("ProductCategoryID")) { 52 boolCategoryId = true; 53 } 54 //競合価格の価格フラグ、Amount判別用 55 if (qName.equalsIgnoreCase("LandedPrice")) { 56 boolLandedPrice = true; 57 } 58 //カテゴリランキング、カテゴリID取得用 59 if (qName.equalsIgnoreCase("SalesRankings")) { 60 boolSR = true; 61 } 62 } 63 64 65 public void characters(char ch[], int start, int length) throws SAXException { 66 if (boolASIN) { 67 asinKey = new String(ch, start, length); 68 map.put(asinKey, submap); 69 boolASIN = false; 70 } 71 if (boolAmount) { 72 if (boolLandedPrice) {//競合価格の値のみ取得 73 map.get(asinKey).put("price", new String(ch, start, length)); 74 boolAmount = false; 75 boolLandedPrice = false; 76 } 77 boolAmount = false; 78 } 79 if (boolOLC) { 80 map.get(asinKey).put("offer", new String(ch, start, length)); 81 boolOLC = false; 82 } 83 if (boolRank){ 84 if (boolSR) { 85 map.get(asinKey).put("rank", new String(ch, start, length)); 86 boolSR = false; 87 } 88 boolRank = false; 89 } 90 if (boolCategoryId){ 91 if (boolSR) { 92 map.get(asinKey).put("category", new String(ch, start, length)); 93// boolSR = false; 94 } 95 boolCategoryId = false; 96 } 97 } 98 99 public void endElement(String uri, String localName, String qName) 100 throws SAXException { 101 if (qName.equalsIgnoreCase("GetCompetitivePricingForASINResult")) { 102 asinKey = null; //ASIN用フィールドをクリア 103// submap.clear(); 104 } 105 } 106 107 public void endDocument(){ 108 // System.out.println("End Document"); 109 } 110 111 public Map<String, Map<String,String>> getMapFromXml (String str) throws Exception { 112 113 InputStream is = new ByteArrayInputStream(str.getBytes("utf-8")); 114 115 SAXParserFactory factory = SAXParserFactory.newInstance(); 116 SAXParser parser = factory.newSAXParser(); 117 SAXSample handler = new SAXSample(); 118 parser.parse(is, handler); //SAX解析 119 120 System.out.println(map.get("B0054IDPBO").get("price"));//←←←ここでNullPointerExceptionになってしまいます。 121 //xmlには値があるのでMapに格納できていると思ったのですが。。 122

当方初学者でコピーペーストでWebサイトをみながらなんとか解析クラスを作ったのですが、
ここで詰まってしまいました。
なぜMapに値を格納できていないのか、どうやったらMapに格納して次のクラスに渡せるか
詳しい方がいらっしゃいましたらご教示いただけると幸いです。

補足情報(FW/ツールのバージョンなど)

xmlはamazonのMWS APIをたたくと得られるものです。
各商品のランキングや価格をプログラムから取得したいので作っています。

コスト面から実行時間はなるべく短くしたいので
DOMではなくSAXで実装したいと考えております。

解析しようとしているxmlはこちらです

xml

1<?xml version="1.0"?> 2<GetCompetitivePricingForASINResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01"> 3 <GetCompetitivePricingForASINResult ASIN="B07CMPXN3H" status="Success"> 4 <Product xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"> 5 <Identifiers> 6 <MarketplaceASIN> 7 <MarketplaceId>A1VC38T7YXB528</MarketplaceId> 8 <ASIN>B07CMPXN3H</ASIN> 9 </MarketplaceASIN> 10 </Identifiers> 11 <CompetitivePricing> 12 <CompetitivePrices> 13 <CompetitivePrice belongsToRequester="false" condition="New" subcondition="New"> 14 <CompetitivePriceId>1</CompetitivePriceId> 15 <Price> 16 <LandedPrice> 17 <CurrencyCode>JPY</CurrencyCode> 18 <Amount>1775.00</Amount> 19 </LandedPrice> 20 <ListingPrice> 21 <CurrencyCode>JPY</CurrencyCode> 22 <Amount>1775.00</Amount> 23 </ListingPrice> 24 <Shipping> 25 <CurrencyCode>JPY</CurrencyCode> 26 <Amount>0.00</Amount> 27 </Shipping> 28 </Price> 29 </CompetitivePrice> 30 </CompetitivePrices> 31 <NumberOfOfferListings> 32 <OfferListingCount condition="New">9</OfferListingCount> 33 <OfferListingCount condition="Any">9</OfferListingCount> 34 </NumberOfOfferListings> 35 </CompetitivePricing> 36 <SalesRankings/> 37 </Product> 38 </GetCompetitivePricingForASINResult> 39 <GetCompetitivePricingForASINResult ASIN="B07YNL3P7K" status="Success"> 40 <Product xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"> 41 <Identifiers> 42 <MarketplaceASIN> 43 <MarketplaceId>A1VC38T7YXB528</MarketplaceId> 44 <ASIN>B07YNL3P7K</ASIN> 45 </MarketplaceASIN> 46 </Identifiers> 47 <CompetitivePricing> 48 <CompetitivePrices/> 49 <NumberOfOfferListings/> 50 </CompetitivePricing> 51 <SalesRankings> 52 <SalesRank> 53 <ProductCategoryId>health_and_beauty_display_on_website</ProductCategoryId> 54 <Rank>49984</Rank> 55 </SalesRank> 56 <SalesRank> 57 <ProductCategoryId>169922011</ProductCategoryId> 58 <Rank>2965</Rank> 59 </SalesRank> 60 </SalesRankings> 61 </Product> 62 </GetCompetitivePricingForASINResult> 63 <GetCompetitivePricingForASINResult ASIN="B0054IDPBO" status="Success"> 64 <Product xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"> 65 <Identifiers> 66 <MarketplaceASIN> 67 <MarketplaceId>A1VC38T7YXB528</MarketplaceId> 68 <ASIN>B0054IDPBO</ASIN> 69 </MarketplaceASIN> 70 </Identifiers> 71 <CompetitivePricing> 72 <CompetitivePrices/> 73 <NumberOfOfferListings> 74 <OfferListingCount condition="New">37</OfferListingCount> 75 <OfferListingCount condition="Any">37</OfferListingCount> 76 </NumberOfOfferListings> 77 </CompetitivePricing> 78 <SalesRankings> 79 <SalesRank> 80 <ProductCategoryId>beauty_display_on_website</ProductCategoryId> 81 <Rank>10782</Rank> 82 </SalesRank> 83 <SalesRank> 84 <ProductCategoryId>169736011</ProductCategoryId> 85 <Rank>64</Rank> 86 </SalesRank> 87 </SalesRankings> 88 </Product> 89 </GetCompetitivePricingForASINResult> 90 <ResponseMetadata> 91 <RequestId>1964bcd9-b42f-4bbe-8e86-087ce1bbbafa</RequestId> 92 </ResponseMetadata> 93</GetCompetitivePricingForASINResponse> 94

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

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

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

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

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

yuokada

2020/02/29 14:07

提示されているXMLに`B0054IDPBO`のキーがみつからないのですが単純なtypoなどではないですか?
KAONAGA9

2020/02/29 14:14

ご指摘ありがとうございました。実際読み込んだデータは文字数制限で入らなかったため一部のみ記載してました。対象のデータを追加させていただきました。
yuokada

2020/02/29 14:56

やりたいこととしてはSAXSample クラスにpublic Map<String, Map<String,String>> getMapFromXml (String str) throws Exception {}を実装してパースした結果を取得したいってことであってますか?
yuokada

2020/02/29 15:08 編集

あと、NullPointerExceptionが出ましただけではなく出来るだけエラーの全文の掲載をお願いします。
KAONAGA9

2020/02/29 15:09

はい、ご指摘の通りです。
guest

回答2

0

ベストアンサー

Javaでxmlを読み込んで内容をDBに保存する処理を作っています。

SAXでxmlを解析してHashMapに値格納したいのですが、
値を取り出そうとするとnullになってしまいます。

目的を実現するのであれば次のようなSampleMainクラスを定義してそこでSAXSampleクラスのインスタンスを生成しXMLをパースしてgetMapFromXml()を呼び出してやればいいと思います。

現在のSAXSampleクラスの中で再度そのクラス自身のインスタンスを生成しパースするのはあまり良いコードとはいえないため、別クラスを定義してそこからgetMapFromXml()を呼び出すのが良いでしょう。

public class SampleMain { public static void main(String[] args) throws Exception { String f = "/path/to/your.xml"; byte[] content = Files.readAllBytes(Paths.get(f)); InputStream in = new ByteArrayInputStream(content); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SAXSample handler = new SAXSample(); parser.parse(in, handler); Map<String, Map<String, String>> m = handler.getMapFromXml("B0054IDPBO"); System.out.println(m); } }
public Map<String, Map<String, String>> getMapFromXml(String mapKey) throws Exception { System.out.println(map.get(mapKey).get("price")); return new HashMap<String, Map<String, String>>(){ {put(mapKey, map.get(mapKey));} }; }

投稿2020/02/29 15:13

yuokada

総合スコア550

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

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

0

SAXにこだわる必要がないのであれば、jackson-dataformat-xmlをつかってみてはどうでしょうか?一発でListとMapの組合せに変換できます。ListとMapからのデータ取得なら、もう少し単純になるのではないでしょうか。

java

1import com.fasterxml.jackson.databind.ObjectMapper; 2import com.fasterxml.jackson.dataformat.xml.XmlMapper; 3 4import java.nio.file.Files; 5import java.nio.file.Paths; 6import java.util.List; 7import java.util.stream.Collectors; 8 9public class ParseXML { 10 public static void main(final String[] args) throws Exception { 11 final String xml = Files.lines(Paths.get("hoge.xml")).collect(Collectors.joining("\n")); 12 13 final List<Object> xmlList = new XmlMapper().readValue(xml, List.class); 14 System.out.println(xmlList); 15 System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"); 16 17 final String json = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(xmlList); 18 System.out.println(json); 19 } 20}

結果

txt

1[{ASIN=B07CMPXN3H, status=Success, Product={Identifiers={MarketplaceASIN={MarketplaceId=A1VC38T7YXB528, ASIN=B07CMPXN3H}}, CompetitivePricing={CompetitivePrices={CompetitivePrice={belongsToRequester=false, condition=New, subcondition=New, CompetitivePriceId=1, Price={LandedPrice={CurrencyCode=JPY, Amount=1775.00}, ListingPrice={CurrencyCode=JPY, Amount=1775.00}, Shipping={CurrencyCode=JPY, Amount=0.00}}}}, NumberOfOfferListings={OfferListingCount={condition=Any, =9}}}, SalesRankings=null}}, {ASIN=B07YNL3P7K, status=Success, Product={Identifiers={MarketplaceASIN={MarketplaceId=A1VC38T7YXB528, ASIN=B07YNL3P7K}}, CompetitivePricing={CompetitivePrices=null, NumberOfOfferListings=null}, SalesRankings={SalesRank={ProductCategoryId=169922011, Rank=2965}}}}, {ASIN=B0054IDPBO, status=Success, Product={Identifiers={MarketplaceASIN={MarketplaceId=A1VC38T7YXB528, ASIN=B0054IDPBO}}, CompetitivePricing={CompetitivePrices=null, NumberOfOfferListings={OfferListingCount={condition=Any, =37}}}, SalesRankings={SalesRank={ProductCategoryId=169736011, Rank=64}}}}, {RequestId=1964bcd9-b42f-4bbe-8e86-087ce1bbbafa}] 2=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

json

1[ { 2 "ASIN" : "B07CMPXN3H", 3 "status" : "Success", 4 "Product" : { 5 "Identifiers" : { 6 "MarketplaceASIN" : { 7 "MarketplaceId" : "A1VC38T7YXB528", 8 "ASIN" : "B07CMPXN3H" 9 } 10 }, 11 "CompetitivePricing" : { 12 "CompetitivePrices" : { 13 "CompetitivePrice" : { 14 "belongsToRequester" : "false", 15 "condition" : "New", 16 "subcondition" : "New", 17 "CompetitivePriceId" : "1", 18 "Price" : { 19 "LandedPrice" : { 20 "CurrencyCode" : "JPY", 21 "Amount" : "1775.00" 22 }, 23 "ListingPrice" : { 24 "CurrencyCode" : "JPY", 25 "Amount" : "1775.00" 26 }, 27 "Shipping" : { 28 "CurrencyCode" : "JPY", 29 "Amount" : "0.00" 30 } 31 } 32 } 33 }, 34 "NumberOfOfferListings" : { 35 "OfferListingCount" : { 36 "condition" : "Any", 37 "" : "9" 38 } 39 } 40 }, 41 "SalesRankings" : null 42 } 43}, { 44 "ASIN" : "B07YNL3P7K", 45 "status" : "Success", 46 "Product" : { 47 "Identifiers" : { 48 "MarketplaceASIN" : { 49 "MarketplaceId" : "A1VC38T7YXB528", 50 "ASIN" : "B07YNL3P7K" 51 } 52 }, 53 "CompetitivePricing" : { 54 "CompetitivePrices" : null, 55 "NumberOfOfferListings" : null 56 }, 57 "SalesRankings" : { 58 "SalesRank" : { 59 "ProductCategoryId" : "169922011", 60 "Rank" : "2965" 61 } 62 } 63 } 64}, { 65 "ASIN" : "B0054IDPBO", 66 "status" : "Success", 67 "Product" : { 68 "Identifiers" : { 69 "MarketplaceASIN" : { 70 "MarketplaceId" : "A1VC38T7YXB528", 71 "ASIN" : "B0054IDPBO" 72 } 73 }, 74 "CompetitivePricing" : { 75 "CompetitivePrices" : null, 76 "NumberOfOfferListings" : { 77 "OfferListingCount" : { 78 "condition" : "Any", 79 "" : "37" 80 } 81 } 82 }, 83 "SalesRankings" : { 84 "SalesRank" : { 85 "ProductCategoryId" : "169736011", 86 "Rank" : "64" 87 } 88 } 89 } 90}, { 91 "RequestId" : "1964bcd9-b42f-4bbe-8e86-087ce1bbbafa" 92} ]

投稿2020/02/29 15:10

shiketa

総合スコア4061

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

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

KAONAGA9

2020/03/01 00:38

JSONにも気軽に変換できるのですね。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問