티스토리 뷰

모바일/Android

Android에서 XML을 처리

공허공자 2011. 11. 11. 18:53

소개

이 기사는 인터넷에서 XML 데이터를 처리 Android 응용 프로그램을 만드는 방법을 배웁니다. 이 Android 애플 리케이션은 Java ™ 프로그래밍 언어로 작성되기 때문에 Java 기술의 경험이 필수입니다. Android 응용 프로그램 개발을 할 Android SDK가 필요합니다. 이 문서에서 설명하는 코드는 어떤 버전의 Android SDK에서도 작동하지만이 기사의 코드 작성에는 SDK 1.5_pre을 사용했습니다. Android 응용 프로그램은 SDK와 텍스트 편집기만으로도 만들 수 있지만 Eclipse 플러그인이다 ADT (Android Developer Tools)를 사용하는 것이 훨씬 쉽습니다. 이 기사에서는 Eclipse 3.4.2의 Java 버전 ADT 버전 0.9을 사용했습니다. 이러한 도구에 대한 링크는 " 참고 자료 "를 참조하십시오.

Android에서 XML

Android 플랫폼은 오픈 소스 모바일 소프트웨어 개발 플랫폼입니다. 이 플랫폼을 사용하여 낮은 수준의 그래픽에서 휴대 전화 카메라와 같은 하드웨어에 이르기까지 Android가 실행되는 모바일 기기의 모든 측면에 액세스할 수 있습니다. 너무 많은 수 Android에 의하여 가능하게되는 경우, 왜 XML에 집착할 필요가 있는지, 이상하게 생각하는 사람이 있을지도 모릅니다. XML을 처리할 수 흥미로운 아니라 XML에 의하여 가능하게되는 것을 취급할 수 흥미로운입니다. XML은 인터넷상의 데이터 포맷으로 일반적으로 사용되고 있습니다. 인터넷의 데이터에 액세스하려는 경우 데이터 형식은 아마 XML입니다.Web 서비스에 데이터를 보낼 경우에도 XML을 보낼 필요가 있습니다. 즉, Android 응용 프로그램에서 인터넷을 활용하고자하는 경우 아마 XML을 취급할 필요가 있습니다. 다행히, Android에서 XML을 다루는 방법은 다양하게 있습니다.

XML 파서

자주 사용하는 약어

  • API : Application Programming Interface
  • RSS : Really Simple Syndication
  • SDK : Software Developers Kit
  • UI : User Interface
  • URL : Universal Resource Locator
  • XML : Extensible Markup Language

Android 플랫폼의 가장 큰 강점 중 하나는 Java 프로그래밍 언어를 사용하는 것입니다. 표준 JRE (Java Runtime Environment)에서 사용할 수있는 모두를 Android SDK가 제공하는 것은 아니지만, JRE의 대부분이 지원되고 있습니다. Java 플랫폼은 XML을 처리하는 다양한 방법을 계속해서 지원 해오고 있으며, XML 관련 Java API의 대부분은 Android도 완벽하게 지원되고 있습니다. 예를 들면, Java의 SAX (Simple API for XML)와 DOM (Document Object Model)은 몇 년 동안 Java 기술의 일부로 사용되는 API이지만 모두 Android 사용할 수 있습니다. 한편, 새로운 StAX (Streaming API for XML)는 Android에서 사용할 수 없지만 대신 Android에는 StAX와 기능적으로 동일한 라이브러리가 포함되어 있습니다.또한 Android에는 Java XML Binding API가 없습니다. 이 API도 Android 구현할 수있을 것입니다. 그러나이 API는 무겁게되어 경향이 있고, 1 개의 XML 문서를 표현하기 위해 다양한 클래스의 인스턴스가 많이 필요할 수 많습니다. 따라서, Android가 실행되는 휴대용 기기처럼 제한된 환경은 Java XML Binding API에는 적합하지 않습니다. 다음 섹션에서는 인터넷에서 사용할 수있는 간단한 XML 소스를 예제에서는 Android 응용 프로그램에서 위의 다양한 API를 사용하여이 XML 소스를 구문 분석하는 방법을 설명합니다. 먼저 인터넷에서 XML을 사용하는 간단한 응용 프로그램 간이되는 부분을 확인합니다.

Android 뉴스 리더

이 응용 프로그램은 Android 개발자 사이트로 인기있는 Androidster에서 RSS 피드를 가져 간단한 Java 개체 목록으로 구문 분석이 목록을 Android의 ListView에서 사용할 수합니다 (소스 코드 " 다운로드 "섹션을 참조하십시오). 이것은 전형적인 다형성 동작입니다. 즉 다른 구현 (다른 XML 구문 분석 알고리즘)에 의해 같은 동작을 실현할 수 있습니다. 인터페이스를 사용하여이 동작을 Java 코드에서 쉽게 모델링하는 방법을 보여 것이 목록 1 입니다.


목록 1. XML 피드 파서 인터페이스
package org.developerworks.android;
import java.util.List;

public interface FeedParser {
    List <Message> parse ();
}

Listing 2  Message 클래스는 데이터 구조를 나타내는 전형적인 POJO (Plain Old Java Object)입니다.


목록 2. Message 는 POJO
public class Message implements Comparable <Message> {
    static SimpleDateFormat FORMATTER = 
        new SimpleDateFormat ( "EEE, dd MMM yyyy HH : mm : ss Z");
    private String title;
    private URL link;
    private String description;
    private Date date;

    // getters and setters omitted for brevity
    public void setLink (String link) {
        try {
            this.link = new URL (link);
        } catch (MalformedURLException e) {
            throw new RuntimeException (e);
        }
    }

    public String getDate () {
        return FORMATTER.format (this.date);
    }

    public void setDate (String date) {
      // pad the date if necessary
        while (! date.endsWith ( "00")) {
            date + = "0";
        }
        try {
            this.date = FORMATTER.parse (date.trim ());
        } catch (ParseException e) {
            throw new RuntimeException (e);
        }
    }
    
    @ Override
    public String toString () {
           // omitted for brevity
    }

    @ Override
    public int hashCode () {
          // omitted for brevity
    }
    
    @ Override
    public boolean equals (Object obj) {
          // omitted for brevity
    }
    // sort by date
    public int compareTo (Message another) {
        if (another == null) return 1;
      // sort descending, most recent first
        return another.date.compareTo (date);
    }
}

Listing 2 의 Message 클래스의 대부분은 간단합니다. Message는 단순한 문자열로 날짜와 링크에 액세스할 수 있도록함으로써 내부 상태의 일부를 숨기는 한편, 강력하게 형식화된 개체로 날짜와 링크를 표현합니다 ( java.util.Date  java.net : URL ). Message는 전형적인 값 개체이므로 내부 상태에 따라 equals ()  hashCode () 를 구현합니다. 또한 Message는Comparable 인터페이스를 구현하기 위해이 인터페이스를 사용하여 (날짜) 정렬할 수 있습니다. 실제로 데이터는 반드시 정렬 상태에서 피드에서 제공되므로 정렬 필요가 없습니다.

각각의 파서 구현은 Androidster 피드 URL을 사용하여 Androidster 사이트에 HTTP 연결을 열어야합니다. 이 공통 동작은 추상 기본 클래스를 사용하여 자연스럽게 Java 코드에서 모델링할 수 있습니다 ( Listing 3 ).


목록 3. 피드 파서의 기본 클래스
public abstract class BaseFeedParser implements FeedParser {

  // names of the XML tags
    static final String PUB_DATE = "pubDate";
    static final String DESCRIPTION = "description";
    static final String LINK = "link";
    static final String TITLE = "title";
    static final String ITEM = "item";
    
    final URL feedUrl;

    protected BaseFeedParser (String feedUrl) {
        try {
            this.feedUrl = new URL (feedUrl);
        } catch (MalformedURLException e) {
            throw new RuntimeException (e);
        }
    }

    protected InputStream getInputStream () {
        try {
            return feedUrl.openConnection () getInputStream ();
        } catch (IOException e) {
            throw new RuntimeException (e);
        }
    }
}

이 기본 클래스는 feedUrl 을 저장하고이 feedUrl 를 사용하여 java.io.InputStream 를 엽니다. 뭔가 문제가있는 경우에는 단순히 RuntimeException 이 발생하므로 응용 프로그램은 즉시 중지합니다. 또한이 기본 클래스는 태그의 이름에 간단한 상수 몇 가지 정의합니다. Listing 4 는이 피드 내용의 예입니다. 이것을 보면 이러한 태그의 중요성을 이해할 수있을 것입니다.


목록 4. XML 피드 예제
<? xml version = "1.0"encoding = "UTF - 8"?>

<! - generator = "FeedCreator 1.7.2"->

<rss version="2.0">
    
  <channel>
        
    <title> android_news </ title>
           
    <description> android_news </ description>
        
    <link> http://www.androidster.com/android_news.php </ link>
        
    <lastBuildDate> Sun, 19 Apr 2009 19:43:45 +0100 </ lastBuildDate>
        
    <generator> FeedCreator 1.7.2 </ generator>
        
    <item>
            
      <title> Samsung S8000 to Run Android, Play DivX, Take Over the 
World </ title>
             
      <link> http://www.androidster.com/android_news/samsung-s8000-to-run-android-
play - divx - take - over - the - world </ link>
            
      <description> More details have emerged on the first Samsung handset 
to run Android. A yet - to - be announced phone called the S8000 is being 
reported ...</ description>
            
      <pubDate> Thu, 16 Apr 2009 07:18:51 +0100 </ pubDate>
        
    </ item>
        
    <item>
            
      <title> Android Cupcake Update on the Horizo​​n </ title>
            
      <link> http://www.androidster.com/android_news/android-cupcake-update-
on - the - horizo​​n </ link>
            
      <description> After months of discovery and hearsay, the Android 
build that we have all been waiting for is about to finally make it 
out ...</ description>
            
      <pubDate> Tue, 14 Apr 2009 04:13:21 +0100 </ pubDate>
        
    </ item>
    
  </ channel>

</ rss>

Listing 4 의 샘플을 보면 알 수 있듯이 ITEM  Message 인스턴스에 해당합니다. item의 자식 노드 ( TITLE , LINK )은 Message인스턴스의 등록 정보에 해당합니다. 이제 피드가 어떤 것인지를 이해하고 공통 부분을 준비 했으니 Android에 제공되는 다양한 기술을 사용하여이 피드를 구문 분석하는 방법을 알아 봅시다. 먼저 SAX에서 시작합니다.

SAX를 사용

Java 환경에서는 빠른 파서가 필요한 경우, 또한 응용 프로그램의 메모리 사용량을 최소화하려면, SAX API가 자주 사용됩니다. 이 점에서 SAX는 Android를 실행하는 모바일 기기에 매우 적합합니다. SAX API는 Java 환경에서 그대로 사용할 수 있으며, Android에서 실행하기 위해 특별한 변경을 할 필요는 없습니다. Listing 5  FeedParser 인터페이스 SAX를 구현하는 예제를 보여줍니다.


목록 5. SAX 구현
public class SaxFeedParser extends BaseFeedParser {

    protected SaxFeedParser (String feedUrl) {
        super (feedUrl);
    }
    
    public List <Message> parse () {
        SAXParserFactory factory = SAXParserFactory.newInstance ();
        try {
            SAXParser parser = factory.newSAXParser ();
            RssHandler handler = new RssHandler ();
            parser.parse (this.getInputStream () handler);
            return handler.getMessages ();
        } catch (Exception e) {
            throw new RuntimeException (e);
        } 
    }
}

SAX를 사용한 적이있는 사람이 구현은 매우 익숙한 것이있을 것입니다. 어떤 SAX 구현의 경우도 마찬가지 입니다만, 자세한 대부분 SAX 핸들러에 있습니다. SAX 핸들러는 XML 문서를 이동하면서 SAX 파서에서 이벤트를 수신합니다. 이 경우에는 RssHandler 라는 새 클래스를 만들고이 클래스를 파서 처리기로 등록합니다 ( Listing 6 ).


목록 6. SAX 핸들러
import static org.developerworks.android.BaseFeedParser .*;

public class RssHandler extends DefaultHandler {
    private List <Message> messages;
    private Message currentMessage;
    private StringBuilder builder;
    
    public List <Message> getMessages () {
        return this.messages;
    }
    @ Override
    public void characters (char [] ch, int start, int len​​gth)
            throws SAXException {
        super.characters (ch, start, length);
        builder.append (ch, start, length);
    }

    @ Override
    public void endElement (String uri, String localName, String name)
            throws SAXException {
        super.endElement (uri, localName, name);
        if (this.currentMessage! = null) {
            if (localName.equalsIgnoreCase (TITLE)) {
                currentMessage.setTitle (builder.toString ());
            } else if (localName.equalsIgnoreCase (LINK)) {
                currentMessage.setLink (builder.toString ());
            } else if (localName.equalsIgnoreCase (DESCRIPTION)) {
                currentMessage.setDescription (builder.toString ());
            } else if (localName.equalsIgnoreCase (PUB_DATE)) {
                currentMessage.setDate (builder.toString ());
            } else if (localName.equalsIgnoreCase (ITEM)) {
                messages.add (currentMessage);
            }
            builder.setLength (0);    
        }
    }

    @ Override
    public void startDocument () throws SAXException {
        super.startDocument ();
        messages = new ArrayList <Message> ();
        builder = new StringBuilder ();
    }

    @ Override
    public void startElement (String uri, String localName, String name,
            Attributes attributes) throws SAXException {
        super.startElement (uri, localName, name, attributes);
        if (localName.equalsIgnoreCase (ITEM)) {
            this.currentMessage = new Message ();
        }
    }
}

org.xml.sax.helpers.DefaultHandler 클래스를 상속 RssHandler 클래스는 SAX 파서에 의해 발생하는 이벤트에 해당하는 모든 메서드에 대한 기본 "아무것도"구현을 제공합니다. 이렇게하면 서브 클래스는 필요에 따라 메서드를 재정의하면 좋은 것입니다. RssHandler 에는 getMessages 라는 또 다른 API가 있습니다. 이 API는 RssHandler 가 SAX 파서에서 이벤트를 수신하면서 수집하는 Message 개체 목록을 반환합니다. RssHandler 에는 이외에도 2 개의 내부 변수가 있습니다 (구문 분석 대상의 Message 인스턴스에 대한 currentMessage 와 텍스트 노드의 문자 데이터를 저장하는 builder  StringBuilder 변수 2 개). 이 2 개의 내부 변수는 모두 해당 이벤트 파서가 처리기에 보내 startDocument 메서드가 호출될 때 초기화됩니다.

Listing 6  startElement 메소드를보세요. 이 메서드는 XML 문서에서 시작 태그를 검출할 때마다 호출되고 태그 ITEM 태그인 경우에만 새로운 Message 를 만듭니다. 다음 characters 메소드를보세요. 이 메서드는 텍스트 노드의 문자 데이터를 감지하면 호출됩니다. 문자 데이터는 단순히 builder 변수에 추가됩니다. 마지막으로, endElement 메서드를보세요. 이 메서드는 종료 태그를 검출하면 호출됩니다. Message 특성에 대응하는 태그 ( TITLE  LINK )의 경우에는 builder 변수의 데이터를 사용하여 적절한 특성이 currentMessage 로 설정됩니다. 종료 태그 ITEM 의 경우에는 currentMessage 가 Messages 목록에 추가됩니다. 이들은 모든 SAX 구문 분석에서 매우 전형적인 것이며, 여기에서는 Android에 특유의 것은 아무것도 실시하지 않습니다. 즉, Java의 SAX 파서를 만드는 방법을 알고 있으면, Android의 SAX 파서를 만드는 방법을 알고있는 것입니다. 그러나 Android SDK에는 SAX에 몇 가지 유용한 기능이 추가되어 있습니다.

SAX의 쉬운 구문 분석

Android SDK에는 android.util.Xml 라는 유틸리티 클래스가 포함되어 있습니다. Listing 7 이 유틸리티 클래스를 사용하여 SAX 파서를 설정하는 방법을 보여줍니다.


목록 7. Android의 SAX 파서
public class AndroidSaxFeedParser extends BaseFeedParser {

    public AndroidSaxFeedParser (String feedUrl) {
        super (feedUrl);
    }

    public List <Message> parse () {
        RssHandler handler = new RssHandler ();
        try {
            Xml.parse (this.getInputStream () Xml.Encoding.UTF_8, handler);
        } catch (Exception e) {
            throw new RuntimeException (e);
        }
        return handler.getMessages ();
    }

}

이 클래스가 여전히 표준 SAX 핸들러를 사용하는 것을주의하십시오. 따라서 위에서 설명한 RssHandler  Listing 7 에서 재사용하고 있습니다. SAX 핸들러를 다시 이용할 수있는 것은 좋은 일이지만 코드가 조금 복잡합니다. 앞의 XML 피드보다 훨씬 더 복잡한 XML 문서를 구문 분석해야하는 경우를 상상해보십시오. 그러한 경우에는 처리기가 버그의 온상이 될 가능성이 있습니다. 예를 들어, Listing 6  endElement 메서드를 다시보세요. 이 메서드는 currentMessage 가 null 여부를 확인하고 등록 정보를 설정하려고하고있는 것을 알게까요? 그리고 이번에는 Listing 4 의 XML 예제를보세요. 이 경우에는 TITLE태그와 LINK 태그 ITEM 태그 밖으로다는 것을주의하십시오. 이 때문에 널 체크를하고 있습니다. 널 체크를하지 않으면 첫 번째 TITLE 태그에 의해 NullPointerException 이 발생합니다. Android에는 SAX API ( Listing 8 ) 자신의 버전을 포함하고 있기 때문에 자신의 SAX 핸들러를 작성할 필요가 없습니다.


목록 8. 단순화된 Android의 SAX 파서
public class AndroidSaxFeedParser extends BaseFeedParser {

    public AndroidSaxFeedParser (String feedUrl) {
        super (feedUrl);
    }

    public List <Message> parse () {
        final Message currentMessage = new Message ();
        RootElement root = new RootElement ( "rss");
        final List <Message> messages = new ArrayList <Message> ();
        Element channel = root.getChild ( "channel");
        Element item = channel.getChild (ITEM);
        item.setEndElementListener (new EndElementListener () {
            public void end () {
                messages.add (currentMessage.copy ());
            }
        });
        item.getChild (TITLE) setEndTextElementListener (new EndTextElementListener () {
            public void end (String body) {
                currentMessage.setTitle (body);
            }
        });
        item.getChild (LINK) setEndTextElementListener (new EndTextElementListener () {
            public void end (String body) {
                currentMessage.setLink (body);
            }
        });
        item.getChild (DESCRIPTION) setEndTextElementListener (new EndTextElementListener () {
            public void end (String body) {
                currentMessage.setDescription (body);
            }
        });
        item.getChild (PUB_DATE) setEndTextElementListener (new EndTextElementListener () {
            public void end (String body) {
                currentMessage.setDate (body);
            }
        });
        try {
            Xml.parse (this.getInputStream () Xml.Encoding.UTF_8, root.getContentHandler ());
        } catch (Exception e) {
            throw new RuntimeException (e);
        }
        return messages;
    }
}

약속대로이 새로운 SAX 파서 코드는 SAX 핸들러가 사용되지 않습니다. 대신 SDK의 android.sax 패키지의 클래스들을 사용하고 있습니다. 이러한 클래스를 사용하면 XML 문서의 구조를 모델링 할 수 있으며 필요에 따라 이벤트 리스너를 추가할 수 있습니다. 위의 코드에서는이 문서는 rss 라는 루트 요소가다는 것을, 그리고이 요소에는 channel 이라는 자식 요소가있는 것을 선언하고 있습니다. 다음 channel 에는 ITEM 이라는 자식 요소가있는 것을 선언하고 청취자의 추가를 시작합니다.각 리스너에 해당 인터페이스 ( EndElementListner 또는 EndTextElementListener )를 구현하는 익명 내부 클래스를 사용합니다. 문자 데이터를 추적할 필요가 없다는 것에 주목하십시오. 이 것이 단순한뿐만 아니라 실제로 효율적입니다. 마지막으로 Xml.parse 유틸리티 메서드를 호출할 때, 이번에는 루트 요소에서 생성된 핸들러를 전달합니다.

위의 Listing 8 의 코드는 옵션입니다. Java 환경에서 표준 SAX 구문 분석 코드가 더 익숙한 사람은 그 쪽을 계속 사용할 수 있습니다. Android SDK에서 제공되는 편리한 래퍼를 시험해보고 싶은 사람이 래퍼를 사용할 수 있습니다. 에서는 절대로 SAX를 사용하고 싶지 않으면 어떻게해야할까요. 이 경우에는 몇 가지 선택이 있습니다. 그 첫 번째 선택으로 DOM을 검사합니다.

DOM 처리

Android는 DOM 구문 분석을 완벽하게 지원되고 있습니다. Android에서 DOM은 데스크톱 컴퓨터 또는 서버에서 실행되는 Java 코드에서 DOM과 마찬가지로 작동합니다. Listing 9 는 파서 인터페이스를 DOM 기반에서 구현한 것입니다.


목록 9. DOM 기반 구현 피드 파서
public class DomFeedParser extends BaseFeedParser {

    protected DomFeedParser (String feedUrl) {
        super (feedUrl);
    }

    public List <Message> parse () {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance ();
        List <Message> messages = new ArrayList <Message> ();
        try {
            DocumentBuilder builder = factory.newDocumentBuilder ();
            Document dom = builder.parse (this.getInputStream ());
            Element root = dom.getDocumentElement ();
            NodeList items = root.getElementsByTagName (ITEM);
            for (int i = 0; i <items.getLength (); i + +) {
                Message message = new Message ();
                Node item = items.item (i);
                NodeList properties = item.getChildNodes ();
                for (int j = 0; j <properties.getLength (); j + +) {
                    Node property = properties.item (j);
                    String name = property.getNodeName ();
                    if (name.equalsIgnoreCase (TITLE)) {
                        message.setTitle (property.getFirstChild () getNodeValue ());
                    } else if (name.equalsIgnoreCase (LINK)) {
                        message.setLink (property.getFirstChild () getNodeValue ());
                    } else if (name.equalsIgnoreCase (DESCRIPTION)) {
                        StringBuilder text = new StringBuilder ();
                        NodeList chars = property.getChildNodes ();
                        for (int k = 0; k <chars.getLength (); k + +) {
                            text.append (chars.item (k). getNodeValue ());
                        }
                        message.setDescription (text.toString ());
                    } else if (name.equalsIgnoreCase (PUB_DATE)) {
                        message.setDate (property.getFirstChild () getNodeValue ());
                    }
                }
                messages.add (message);
            }
        } catch (Exception e) {
            throw new RuntimeException (e);
        } 
        return messages;
    }
}

처음 SAX 예제 에서처럼이 코드 Android에 특유의 아무것도 없습니다. DOM 파서는 XML 문서 전체를 메모리에로드합니다.그런 다음 DOM API를 사용하여 XML 트리를 횡단하고 필요한 데이터를 가져옵니다. 이것은 매우 간단 코드이며 어떤 면에서는 SAX 기반 구현보다 간단합니다. 그러나 DOM은 모든 것이 처음 메모리에로드되기 때문에 일반적으로 DOM 더 많은 메모리를 소비합니다. 이것은 Android를 실행하는 모바일 기기에서 문제가 될 수도 있지만, XML 문서의 크기가 너무 커지지 않는 특정 사용에서는 만족할 수있는 수준 할지도 모릅니다. 상상이지만, Android 개발자들은 Android 응용 프로그램은 SAX 구문 분석이 훨씬 일반적인 추측했기 때문에 SAX 구문 분석을위한 추가 유틸리티가 포함되어있는지도 모른다 않습니다. Android는 또 다른 유형의 XML 파서를 사용할 수 있습니다. 그것이 풀 파서입니다.

XML 풀 파서

앞서 언급했듯이, Android는 Java의 StAX API를 지원하지 않습니다. 그러나 Android는 StAX처럼 작동 풀 파서이 준비되어 있습니다. 이 풀 파서을 사용하면 응용 프로그램 코드가 파서에서 이벤트를 풀하거나 검색할 수 있습니다. 이것은 이벤트를 자동으로 처리기에 밀어 SAX 파서는 대조적입니다. Listing 10 은 피드 파서 인터페이스 풀 파서를 구현한 예입니다.


목록 10 풀 파서 기반 구현
public class XmlPullFeedParser extends BaseFeedParser {
    public XmlPullFeedParser (String feedUrl) {
        super (feedUrl);
    }
    public List <Message> parse () {
        List <Message> messages = null;
        XmlPullParser parser = Xml.newPullParser ();
        try {
          // auto - detect the encoding from the stream
            parser.setInput (this.getInputStream (), null);
            int eventType = parser.getEventType ();
            Message currentMessage = null;
            boolean done = false;
            while (eventType! = XmlPullParser.END_DOCUMENT & &! done) {
                String name = null;
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT :
                        messages = new ArrayList <Message> ();
                        break;
                    case XmlPullParser.START_TAG :
                        name = parser.getName ();
                        if (name.equalsIgnoreCase (ITEM)) {
                            currentMessage = new Message ();
                        } else if (currentMessage! = null) {
                            if (name.equalsIgnoreCase (LINK)) {
                                currentMessage.setLink (parser.nextText ());
                            } else if (name.equalsIgnoreCase (DESCRIPTION)) {
                                currentMessage.setDescription (parser.nextText ());
                            } else if (name.equalsIgnoreCase (PUB_DATE)) {
                                currentMessage.setDate (parser.nextText ());
                            } else if (name.equalsIgnoreCase (TITLE)) {
                                currentMessage.setTitle (parser.nextText ());
                            }    
                        }
                        break;
                    case XmlPullParser.END_TAG :
                        name = parser.getName ();
                        if (name.equalsIgnoreCase (ITEM) & & currentMessage! = null) {
                            messages.add (currentMessage);
                        } else if (name.equalsIgnoreCase (CHANNEL)) {
                            done = true;
                        }
                        break;
                }
                eventType = parser.next ();
            }
        } catch (Exception e) {
            throw new RuntimeException (e);
        }
        return messages;
    }
}

풀 파서 동작은 SAX 파서의 동작과 비슷합니다. 풀 파서는 SAX 파서의 경우와 비슷한 이벤트 (시작 요소 끝 요소)가 있습니다만, 그 이벤트에서 끌어해야합니다 ( parser.next () ). 이벤트는 숫자 코드로 전송되기 때문에 간단한 case - switch를 사용할 수 있습니다. 주의할 점은 풀 파서 구문 분석은 SAX 구문 분석과 같은 요소의 종료를 수신하는 것이 아니라 대부분의 작업을 먼저 실시한다고 간단한 것입니다. Listing 10 의 코드의 경우 요소가 시작되면 parser.nextText () 를 호출하여 XML 문서에서 모든 문자 데이터를 끌어 있습니다. 이것은 SAX 구문 분석보다 좋게 단순화되어 있습니다. 또한 관심이있는 대상의 끝에 도달하면 끝까지 도달했다는 것을 나타내기 위해 플래그 (부울 변수 done )을 설정하고있는 것도 주목하십시오. 이렇게하면 문서의 나머지는 코드로 처리되지 않는 부분임을 알 수 있으므로 XML 문서 읽기를 초기에 정지시킬 수 있습니다. 이것은 읽기 대상 XML 문서의 극히 일부분만이 필요한 경우에는 아주 효과적이며, 가능한 초기에 구문 분석을 중지시키는 것으로, 구문 분석 시간을 크게 단축할 수 있습니다 . 다시 말하지만, 이런 종류의 최적화는 연결 속도가 느릴 수있는 모바일 기기에 특히 중요합니다. 풀 파서는 성능 측면에서 몇 가지 장점이있을뿐만 아니라 사용의 용이성 측면에서 우수합니다. 풀 파서는 XML을 만드는 데 사용할 수 있습니다.

XML 만들기

지금까지 인터넷에서 XML의 구문 분석에 초점을 맞추고 왔습니다. 그러나 경우에 따라 응용 프로그램이 원격 서버에 XML을 전송해야 할 수 있습니다. 물론, StringBuilder 등을 사용하여 XML 문자열을 만들 수도 있지만 다른 선택으로 풀 파서를 사용하는 방법이 있습니다 ( Listing 11 ).


목록 11. 풀 파서를 사용하여 XML 만들기
private String writeXml (List <Message> messages) {
    XmlSerializer serializer = Xml.newSerializer ();
    StringWriter writer = new StringWriter ();
    try {
        serializer.setOutput (writer);
        serializer.startDocument ( "UTF - 8", true);
        serializer.startTag ( "", "messages");
        serializer.attribute ( "", "number", String.valueOf (messages.size ()));
        for (Message msg : messages) {
            serializer.startTag ( "", "message");
            serializer.attribute ( "", "date", msg.getDate ());
            serializer.startTag ( "", "title");
            serializer.text (msg.getTitle ());
            serializer.endTag ( "", "title");
            serializer.startTag ( "", "url");
            serializer.text (msg.getLink () toExternalForm ());
            serializer.endTag ( "", "url");
            serializer.startTag ( "", "body");
            serializer.text (msg.getDescription ());
            serializer.endTag ( "", "body");
            serializer.endTag ( "", "message");
        }
        serializer.endTag ( "", "messages");
        serializer.endDocument ();
        return writer.toString ();
    } catch (Exception e) {
        throw new RuntimeException (e);
    }
}

XmlSerializer 클래스는 이 이전 섹션 에서 사용한 XmlPullParser 와 같은 패키지의 일부입니다. 이 클래스는 이벤트를 끌어 대신 이벤트를 스트림, 즉 라이터에 푸시합니다. 이 경우에는 XmlSerializer 클래스는 단순히 이벤트를java.io.StringWriter 인스턴스에 푸시합니다. 이 클래스는 문서의 시작과 끝 요소의 처리, 그리고 텍스트 또는 속성 추가를위한 메서드를 제공하는 단순한 API로 작동합니다. 따라서 StringBuilder 를 사용하는 것보다 XmlSerializer 클래스를 사용하는 것이 편리합니다. XmlSerializer 클래스를 사용하면 XML은 확실히 형식이 생성되기 때문입니다.

정리

여러분은 Android 기기에 어떤 응용 프로그램을 작성 해보고 있을까요? 응용 프로그램이 어떤 것이든, 인터넷의 데이터를 다루는 경우 아마도 응용 프로그램은 XML을 취급할 필요가 있습니다. 이 문서에서는 Android는 XML을 처리하는 도구가 풍부하게 포함되어있다는 것을 설명했습니다. 그러한 가운데에서, 마음 도구를 하나만 선택할 수도 있고, 또는 사용에 따라 다양한 도구를 구분 수도 있습니다. 대부분의 경우 SAX를 선택하면 안전하고 Android에는 전통적인 방법에서 SAX 사용법과 SAX에 래핑된 편리하고 뛰어난 래퍼를 사용하는 방법이 모두 포함되어 있습니다. 문서가 작은 경우에는 아마도 DOM을 사용하는 것이 쉽습니다. 문서가 크고, 그러나 문서의 일부 분만 필요하지 않은 경우에는 XML 풀 파서를 사용하는 것이 효율적지도 모릅니다. 그리고 마지막으로, XML을 만드는 경우 풀 파서 패키지를 사용하면 XML의 작성도 간편하게 실시할 것을 설명했습니다. 즉, XML에 관해서 어떤 것이 필요한 경우에도 Android SDK는 반드시 무언가를 제공해 줄 것입니다.


다운로드

파일 이름크기다운로드 형식
AndroidXml.zip 70KB HTTP

다운로드 형식에 대해


참고 문헌

배우기 위하여

  • " Develop Android applications with Eclipse "(Frank Ableson의, developerWorks, 2008 년 2 월)를 읽어보십시오. Android 응용 프로그램을 만드는 데 가장 쉬운 방법은 Eclipse를 사용하는 것입니다. 이 연습에서는 그 모든 것을 배울 수 있습니다.

  • SAX, DOM, 그리고 풀 파서를 비교한 기사로 " Geronimo에 전향 : 통합 패키지 사용 : Codehaus의 Woodstox "(Michael Galpin의, developerWorks, 2007 년 7 월)도 읽어보십시오.

  • " StAX에서 XML을 처리하는 제 2 회 : 끌어 오기 분석 및 이벤트 "(Peter Nehrer의, developerWorks, 2006 년 12 월) XML 풀 파서을 자세히 설명하고 있습니다.

  • 이 자습서, " Understanding SAX "(Nicholas Chase의, developerWorks, 2003 년 7 월)을 읽고 SAX 구문 분석의 전문가가되어주세요.

  • 이 자습서, " Understanding DOM "(Nicholas Chase의, developerWorks, 2007 년 3 월)는 DOM 구문 분석에 대해 자세히 설명하고 있습니다.

  • Android SDK 문서 를 읽고 응용 프로그램 코드 작성 및 디버깅, 그리고 응용 프로그램의 UI 디자인을위한 도구 세트인 Android SDK에 대해 알아보십시오.

  • Open Handset Alliance 에 대해 확인하십시오. Open Handset Alliance는 Android의 스폰서이며, 모바일 기술의 혁신을 가속 화하기 위해 협력하는 47 개사로 구성되어 있습니다.

  • XML 및 관련 기술에서 IBM 인증 개발자가되는 방법은 IBM XML certification 을 참조하십시오.

  • developerWorks의 XML 영역 XML 기술 라이브러리 로 사용하십시오. 다양한 주제를 다루는 기술 기사와 팁, 튜토리얼, 표준, IBM Redbooks 등이 준비되어 있습니다.

  • developerWorks의 Technical events and webcasts 최신 정보를 입수하십시오.

  • developerWorks podcasts 에서 소프트웨어 개발자의 흥미로운 인터뷰와 토론을들을 수 있습니다.

제품 및 기술 얻기

  • Android 개발자 공식 사이트에서 Android SDK 를 다운로드하여 API 문서에 액세스하고 Android의 최신 뉴스를 구하십시오.

  • Android Open Source Project 에서 Android 오픈 소스 코드를 구하십시오.

  • Eclipse IDE 의 최신 버전을 검색하여 활용하십시오.

  • IBM 제품 평가판 을 다운로드하거나 온라인으로 IBM SOA Sandbox 를 시도하고 DB2 ®, Lotus ®, Rational ®, Tivoli ® 및 WebSphere ®의 애플 리케이션 개발 도구와 미들웨어 제품을 사용해보십시오.

논의하기 위해

저자에 관하여

Michael Galpin 's photo

Michael Galpin은 eBay의 설계자입니다. 그는 developerWorks에 정기적으로 기고하고 있으며 TheServerSide.com 및 Java Developer 's Journal, 그리고 그 자신의 블로그 에 기사를 집필하고 있습니다. 그는 1998 년부터 프로로 프로그래밍을하고 있으며, California Institute of Technology에서 수학 학위를 취득하고 있습니다.


원본 = http://www.ibm.com/developerworks/opensource/library/x-android/index.html

'모바일 > Android' 카테고리의 다른 글

안드로이드 JSON 파싱  (0) 2011.11.27
쓰레드(Thread) 와 핸들러(Handler)  (0) 2011.11.17
[앱-게임] 데스티니아  (0) 2011.11.07
에픽하츠 설치 요구사항  (0) 2011.11.01
써드블레이드 설치 요구사항  (2) 2011.11.01
댓글