프로그래밍/Spring Framework

네이버개발자센터 OPEN API XML 파싱 (SAX방식)

2016. 6. 23. 17:56


네이버개발자센터 


OPEN API XML 파싱 


(SAX방식)





XML이란 

트리구조의 데이터를 단순히 텍스트형태로 나타낸 것 



XML 파싱방법에는 두가지가 있습니다. 

DOM 파싱 / SAX 파싱 

DOM: 메모리에 모두 로드한 후 파싱/ 빠름/ 메모리사용량이 많음 

SCM : 순차적으로 읽어가며 파싱 / 메모리 사용량이 적고 / 미래를 모르기 떄문에 여러 기능에 제한 



-> 현재는 JSON을 많이 씁니다.

이유는 XML이 무겁고........................기타 여러가지 이유로! 







EClipse에서 

JAVA project를 생성하고 

MAVEN Project로 설정해줍니당 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>NaverBookAPI</groupId>
  <artifactId>NaverBookAPI</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  
  <dependencies>
      <dependency>
        <groupId>net.sf.sociaal</groupId>
        <artifactId>xmlpull-xpp3</artifactId>
        <version>3.0.0.20130526</version>
    </dependency>
  </dependencies>
</project>
cs


XML 파싱하기 위해서 

pom.xml에 다음과같은 dependency를 설정해줍니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
 
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
 
public class Test {
    public static void main(String[] args) throws Exception{
 
        String clientID="";
        String clientSecret = "";
        URL url = new URL("https://openapi.naver.com/v1/search/book.xml?query=java");
        
        URLConnection urlConn=url.openConnection(); //openConnection 해당 요청에 대해서 쓸 수 있는 connection 객체 
        
        urlConn.setRequestProperty("X-Naver-Client-ID", clientID);
        urlConn.setRequestProperty("X-Naver-Client-Secret", clientSecret);
        
        BufferedReader br = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
        
        String data="";
        String msg = null;
        while((msg = br.readLine())!=null)
        {
//            System.out.println(msg);
            data += msg;
        }
        
        List<Book> list = null//결과데이터 담을 리스트 
//        System.out.println(data); //응답받은 xml문서 xml문서로부터 내가 원하는 값 탐색하기(xml 파싱)
         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
         XmlPullParser parser = factory.newPullParser(); //연결하는거 담고 
         parser.setInput(new StringReader(data));
         int eventType= parser.getEventType();
         Book b = null;
         while(eventType != XmlPullParser.END_DOCUMENT){
             switch(eventType){
             case XmlPullParser.END_DOCUMENT://문서의 끝 
                 break;
             case XmlPullParser.START_DOCUMENT:
                 list = new ArrayList<Book>();
                 break;
             case XmlPullParser.START_TAG:{ //무조건 시작하면 만남 
                 String tag = parser.getName();
                 switch(tag){
                 case "items"//items가 열렸다는것은 새로운 책이 나온다는것 
                     b = new Book();
                     break;
                 case "title":
                     System.out.println(parser.nextText());
                     break;
                 }
                 break;
             }
         }
             eventType =parser.next();
    
    }
    for(Book book:list)
        System.out.println(book);
    }
}
 
cs



         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
         XmlPullParser parser = factory.newPullParser(); //연결하는거 담고 
         parser.setInput(new StringReader(data));


xml을 파싱하기 위해 XmlPullParser클래스를 사용합니당 

그리고 데이터를 읽습니다. 


int eventType= parser.getEventType();

위의 소스는 

코드의 시작과 끝을 알려주는것을 의미합니다 


문서가 끝나지 않을때까지 반복합니다 


END_DOCUMENT : 문서의 끝

START_TAG : 태그의 시작 

END_TAG: 태그의 끝

TEXT : 태그의 시작과 끝 사이에 나타남


하지만


XmlPullParser는 순차적으로 문서를 읽어가면서 이벤트를 발생시켜서 

뒤로 돌아가지못하는 문제를 발생합니다. 

그래서 이를 해결하기 위해 

START_TAG 이벤트가 발생하면 임시변수에 Tag값을 저장 

저장된 Tag값을 확인하여 적절한 변수에 값을 넣어야합니당 



XmlPullParser.START_Tag와 XmlPullParser.END_TAG에서는 getName() 사용 

XmlPullParser.TEXT에서는 getText()사용 

사용하지 않으면 null값을 반환 



실행하면 

위와같이 title이 출력되는 것을 확인 할 수 있습니다. 





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
 
public class Book {
    private String title;
    private String link;
    private String imag;
    private String author;
    private String price;
    private String discount;
    private String publisher;
    private String pubdate;
    private String isbn;
    private String description;
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getLink() {
        return link;
    }
    public void setLink(String link) {
        this.link = link;
    }
    public String getImag() {
        return imag;
    }
    public void setImag(String imag) {
        this.imag = imag;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    public String getDiscount() {
        return discount;
    }
    public void setDiscount(String discount) {
        this.discount = discount;
    }
    public String getPublisher() {
        return publisher;
    }
    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }
    public String getPubdate() {
        return pubdate;
    }
    public void setPubdate(String pubdate) {
        this.pubdate = pubdate;
    }
    public String getIsbn() {
        return isbn;
    }
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    @Override
    public String toString() {
        return "Book [title=" + title + ", link=" + link + ", imag=" + imag + ", author=" + author + ", price=" + price
                + ", discount=" + discount + ", publisher=" + publisher + ", pubdate=" + pubdate + ", isbn=" + isbn
                + ", description=" + description + "]";
    }
    
}
 
cs


네이버 개발자 센터의 출력결과를 보고 

Book클래스를 만들어줍니다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
 
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
 
public class Test {
    public static void main(String[] args) throws Exception{
      
        String clientID="";
        String clientSecret = "";
        URL url = new URL("https://openapi.naver.com/v1/search/book.xml?query=java");

        
        URLConnection urlConn=url.openConnection(); //openConnection 해당 요청에 대해서 쓸 수 있는 connection 객체 
        
        urlConn.setRequestProperty("X-Naver-Client-ID", clientID);
        urlConn.setRequestProperty("X-Naver-Client-Secret", clientSecret);
        
        BufferedReader br = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
        
        String data="";
        String msg = null;
        while((msg = br.readLine())!=null)
        {
//            System.out.println(msg);
            data += msg;
        }
        
        List<Book> list = null//결과데이터 담을 리스트 
//        System.out.println(data); //응답받은 xml문서 xml문서로부터 내가 원하는 값 탐색하기(xml 파싱)
         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
         XmlPullParser parser = factory.newPullParser(); //연결하는거 담고 
         parser.setInput(new StringReader(data));
         int eventType= parser.getEventType();
         Book b = null;
         while(eventType != XmlPullParser.END_DOCUMENT){
             switch(eventType){
             case XmlPullParser.END_DOCUMENT://문서의 끝 
                 break;
             case XmlPullParser.START_DOCUMENT:
                 list = new ArrayList<Book>();
                 break;
             case XmlPullParser.END_TAG:{
                 String tag = parser.getName();
                 if(tag.equals("item")){
                     list.add(b);
                     b = null;
                 }
             }
                 
                 
             case XmlPullParser.START_TAG:{ //무조건 시작하면 만남 
                 String tag = parser.getName();
                 switch(tag){
                 case "item"//item가 열렸다는것은 새로운 책이 나온다는것 
                     b = new Book();
                     break;
                 case "title":
                     if(b!=null)
                         b.setTitle(parser.nextText());
                     break;
                 case "link":
                     if(b!=null)
                         b.setLink(parser.nextText());
                     break;
                 case "image":
                     if(b!=null)
                         b.setImag(parser.nextText());
                     break;
                 case "author":
                     if(b!=null)
                         b.setAuthor(parser.nextText());
                     break;
                 case "price":
                     if(b!=null)
                         b.setPrice(parser.nextText());
                     break;
                 case "discount":
                     if(b!=null)
                         b.setDiscount(parser.nextText());
                     break;
                 case "pubdate":
                     if(b!=null)
                         b.setPubdate(parser.nextText());
                     break;
                 case "isbn":
                     if(b!=null)
                         b.setIsbn(parser.nextText());
                     break;
                 case "description":
                     if(b!=null)
                         b.setDescription(parser.nextText());
                     break;
                 }
                 break;
             }
         }
             eventType =parser.next();
    
    }
    for(Book book:list)
        System.out.println(book);
    }
}
cs




(->네이버 책 검색 API 저장되어있는 예시입니다! 

네이버 개발자센터 개발가이드에 있습니다 )





eventType에 따라 실행하게 됩니다. 

문서가 시작되면 

ArrayLIst를 만들고 

item이 입력되면

새로운 Book 을 생성하고 

순서대로 

book의 title, link등을 넣어주게됩니당 


태그가 끝날 때 

배열에 book을 넣어주고 

다시 Book은 null로! 

-> 새로운 것을 받아서 읽고 그래야되니까요! 





for문을 돌려서 출력을 하면 

위와같이 나옵니다:)