<?xml version="1.0"?>
<rss version="2.0">
<channel>
  <title>좋은생각 - XML category</title>
  <link>http://goodidea.blogsite.org/categories/xml/</link>
  <description>크게 성공한 사람은 작은 성공을 계속하는 사람일 뿐이다. -- 크리스토퍼 몰리</description>
  <language>ko</language>
  <copyright>고진혁</copyright>
  <lastBuildDate>Tue, 22 Sep 2009 02:25:53 GMT</lastBuildDate>
  <generator>Pebble (http://pebble.sourceforge.net)</generator>
  <docs>http://backend.userland.com/rss</docs>
  
  
  <item>
    <title>StAX (Streaming API for XML) 살펴보기 </title>
    <link>http://goodidea.blogsite.org/2007/11/14/1195030098922.html</link>
    
      
        <description>
          StAX (Streaming API for XML) 살펴보기   write by Ko,jinhyuk  2007. 11. 14 ~&lt;br /&gt;
&lt;br /&gt;
Axis2 가 성능향상의 한가지 요인으로 파서의 변경으로 꼽았는데..  기존의 SAX(Simple API for XML) 파싱(이벤트 방식의  push-parsing )을   pull-parsing이라고 하는 StAX (Streaming API for XML) 으로의 변경이다.&lt;br /&gt;
&lt;br /&gt;
StAX 는 기존파서 (SAX와 DOM)와 비교 해보면 기존의 SAX 파싱은 이벤트방식으로  빠르지만 다루기 불편하고 DOM은 트리구조라  다루기는 편리하지만 속도가 느린점이 단점이었는데    StAX는 SAX처럼 빠르면서 비교적 DOM처럼 다루기 편리한 그래서 전체적으로 XML Processing이 빨라지게 하는 성능향상 효과를 제공한다 이점이 있다.&lt;br /&gt;
&lt;br /&gt;
StAX 는  http://jcp.org/en/jsr/detail?id=173 에서 제안요청된 것으로  2004년3월25일에 첫 릴리즈가 되었다.  그동안은 나도 모르고 지내다가... Axis2 로 웹서비스 프레임워크를 바꾸면서 접하게 되었고 이를 이용해서 기존에 파싱처리하던 로직에도 개선을 좀 해보고자 한다.&lt;br /&gt;
&lt;br /&gt;
JDBC나 Servlet 이 그렇듯 StAX에 대한 표준 스펙을 여러곳에서 구현했는데 그중에서도 (아무래도) Axis2가 사용하고 있는 Jar가 좋을것이라고 예상하고   Axis2 에 포함된걸 찾아보았는데&lt;br /&gt;
&lt;br /&gt;
StAX 로 보이는 jar가 2개가 있다.&lt;br /&gt;
&lt;strong&gt;stax-api-1.0.1.jar&lt;/strong&gt; : StAX의 패키지와 클래스를 참조할수있도록 하는 인터페이스 정의 jar 파일&lt;br /&gt;
&lt;strong&gt;wstx-asl-3.2.1.jar&lt;/strong&gt; : codehaus.org 의 오픈소스 커뮤니티에 참여중인 StAX프로젝트(http://stax.codehaus.org/)와 Woodstox 프로젝트(http://woodstox.codehaus.org/) 의 StAX의 구현 실체 jar 파일. (파일을 보면 com.ctc.x.x 와 org.x.x.x 두가지가 있다.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
stax.codehaus.org 의 구현 jar는 RI (Reference Implementation ; core적인 아주 기본적 구현만을 한것으로 다른 구현 라이브러리들이 만들어 질수있도록 하는 common 라이브러리 내지는 참조용 같은것 )이다. 여기에 부가적으로 필요한 DTD-validation 등을 구현 하고 추가해서 &lt;a href=&#034;http://woodstox.codehaus.org/3.2.2/wstx-asl-3.2.2.jar&#034;&gt;wstx-asl-3.2.2.jar (ASL 2.0)&lt;/a&gt; 패키지 하나로 묶었다.&lt;br /&gt;
그래서 실제 상용 개발에서는 Woodstox 버전을 이용하면 되겠다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
이렇게 해서 한번 parsing을 돌려봐야 할텐데   아래에 sample를 만들어봤다... 기존에 있던 소스들을 짜깁기해서... ^^;&lt;br /&gt;
===================================================================&lt;br /&gt;
&lt;br /&gt;
package org.blogsite.goodidea.sample.test;&lt;br /&gt;
&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.io.InputStream;&lt;br /&gt;
import java.io.PrintStream;&lt;br /&gt;
import java.net.Authenticator;&lt;br /&gt;
import java.net.PasswordAuthentication;&lt;br /&gt;
import java.net.URL;&lt;br /&gt;
&lt;br /&gt;
import javax.xml.stream.XMLInputFactory;&lt;br /&gt;
import javax.xml.stream.XMLStreamConstants;&lt;br /&gt;
import javax.xml.stream.XMLStreamException;&lt;br /&gt;
import javax.xml.stream.XMLStreamReader;&lt;br /&gt;
&lt;br /&gt;
import java.security.*;&lt;br /&gt;
&lt;br /&gt;
import junit.framework.TestCase;&lt;br /&gt;
&lt;br /&gt;
public class StAXTestPack extends TestCase {&lt;br /&gt;
&lt;br /&gt;
public void testParse(){&lt;br /&gt;
&lt;br /&gt;
// factory용 인스턴스 만들고&lt;br /&gt;
XMLInputFactory factory = XMLInputFactory.newInstance();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PrintStream out = System.out;&lt;br /&gt;
&lt;br /&gt;
InputStream input;&lt;br /&gt;
XMLStreamReader r=null;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
이부분은 만일 Basic Authentication 을 해야 하는 경우에활용하면 되겠다.&lt;br /&gt;
&lt;br /&gt;
Authenticator.setDefault(new Authenticator() {&lt;br /&gt;
protected PasswordAuthentication getPasswordAuthentication() {&lt;br /&gt;
return new PasswordAuthentication(&amp;quot;아이뒤&amp;quot;,&amp;quot;비번&amp;quot;.toCharArray());&lt;br /&gt;
}&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
*/    &lt;br /&gt;
try {&lt;br /&gt;
URL url = new URL(&amp;quot;http://서버:포트번호/경로1/경로2/대상파일명.xml&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
input = url.openStream();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
r = factory.createXMLStreamReader(input);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int event = r.getEventType();&lt;br /&gt;
while (true) {&lt;br /&gt;
switch (event) {&lt;br /&gt;
case XMLStreamConstants.START_DOCUMENT:&lt;br /&gt;
out.println(&amp;quot;Start Document.&amp;quot;);&lt;br /&gt;
break;&lt;br /&gt;
case XMLStreamConstants.START_ELEMENT:&lt;br /&gt;
out.println(&amp;quot;Start Element: &amp;quot; + r.getName());&lt;br /&gt;
for(int i = 0, n = r.getAttributeCount(); i &amp;lt; n; ++i)&lt;br /&gt;
out.println(&amp;quot;Attribute: &amp;quot; + r.getAttributeName(i)&lt;br /&gt;
+ &amp;quot;=&amp;quot; + r.getAttributeValue(i));&lt;br /&gt;
&lt;br /&gt;
break;&lt;br /&gt;
case XMLStreamConstants.CHARACTERS:&lt;br /&gt;
if (r.isWhiteSpace())&lt;br /&gt;
break;&lt;br /&gt;
&lt;br /&gt;
out.println(&amp;quot;Text: &amp;quot; + r.getText());&lt;br /&gt;
break;&lt;br /&gt;
case XMLStreamConstants.END_ELEMENT:&lt;br /&gt;
out.println(&amp;quot;End Element:&amp;quot; + r.getName());&lt;br /&gt;
break;&lt;br /&gt;
case XMLStreamConstants.END_DOCUMENT:&lt;br /&gt;
out.println(&amp;quot;End Document.&amp;quot;);&lt;br /&gt;
break;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
if (!r.hasNext())&lt;br /&gt;
break;&lt;br /&gt;
&lt;br /&gt;
event = r.next();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
}catch (XMLStreamException e) {&lt;br /&gt;
// TODO Auto-generated catch block&lt;br /&gt;
e.printStackTrace();&lt;br /&gt;
}catch (IOException e) {&lt;br /&gt;
// TODO Auto-generated catch block&lt;br /&gt;
e.printStackTrace();&lt;br /&gt;
this.assertNull(e);&lt;br /&gt;
} finally {&lt;br /&gt;
try {&lt;br /&gt;
if(r!=null)&lt;br /&gt;
r.close();&lt;br /&gt;
} catch (XMLStreamException e) {&lt;br /&gt;
// TODO Auto-generated catch block&lt;br /&gt;
e.printStackTrace();&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
==========================================================================&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
이렇게 해서 예제 소스를 돌려보고 나면 과연 기존보다 무엇이 좋은것인가 싶다.... &lt;br /&gt;
Push -&amp;gt; Pull 방식을 파싱이 바뀌었다는게  기존에는 parse() 호출하고 나면 파서가  event 를 callback 방식으로 불러주었기에  피동적으로 모든 이벤트를 기다렸다면 위에 pull 방식은 내가 jdbc 레코드 커서옮기듯이 (Cursor 방식) next()를 하면서 다음 XML 의 element들을 찾아내서 처리하는 것이다. 처리하다가 예외가 있으면 바로 중단 해버릴수도있고 비교적 능동적 처리가 가능 하다는 점인데... 쩝.  해보고 나니 마치 기존에 SAX 파싱에 파서입장에서  callback 함수를 불러주기 전단계라고 보여진다. swich - case 문으로 하다보니 내부적으로 다른 함수를 불러서 처리하고픈 본능이 생기는 데 그럼 결국 같은거 아닌가 싶기도 하고 .   그래서  기존에 SAX 파싱으로 잘쓰고 있는 소스인경우에는 굳이 바꿀필요는 없을것같다. 다만 XML 이 복잡하고 약간의 시간이라도 최소화 하고자 할때에는 조금 더 유리할수는 있겠다.&lt;br /&gt;
&lt;br /&gt;
처리방식에있어서는 위와 같은 형태가 대표적인 케이스고... 내부에서 Streaming handling이 좀더 빠라졌는지는 모르겠는데 이에 대한건 실험을 해봐야 할것같은데.. 누가 해준자료가 있음 좋겠다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
일단 여기까지 하고 좀더써보면서  획기적인게 있으면 추가로 글에 첨가 해야 겠다.
        </description>
      
      
    
    
    
    <category>XML</category>
    
    <comments>http://goodidea.blogsite.org/2007/11/14/1195030098922.html#comments</comments>
    <guid isPermaLink="true">http://goodidea.blogsite.org/2007/11/14/1195030098922.html</guid>
    <pubDate>Wed, 14 Nov 2007 08:48:18 GMT</pubDate>
  </item>
  
  </channel>
</rss>
