(Extensible Markup Language (XML) 1.0 (Fifth Edition))
XML 파서의 종류는 SAX 파서와 DOM 파서가 있다.
SAX 파서와 DOM 파서의 차이점:
참고 - http://www.ibiblio.org/xml/books/xmljava/chapters/ch09s11.html
(Choosing between SAX and DOM)
> 요약: 어떤 파서를 사용할지는 아래와 같은 상황을 고려하여 선택하는 편이 좋다.
SAX 파서를 사용하는 상황
- 파싱하려는 XML 크기가 너무 클 때
- 파싱하려는 XML 중 필요한 정보만 취합하고자 할 때
- 실시간으로 파싱을 처리하고자 할때
DOM 파서를 사용하는 상황
- XML 문서안에 넓게 분포된 자료들 한번에 취합하고자 할 때
- 파싱하려는 XML 문서 구조가 매우 복잡할 때
- XML 문서를 수정할 때
- 파싱한 XML 정보를 여러 함수들이 사용하고자 할 때
파서 사용법:
예) RSS 파일을 파싱하는 예
NY times 사이트의 RSS 링크 중 하나를 선택하여 nyfeed.xml 이라는 파일명으로 저장하였다.
RSS 항목들 중 item 항목에 대한 title 과 link 만 추려서 출력한다.
프로젝트 구조는 아래와 같다.
실행 결과는 아래와 같다.
nyfeed.xml
XMLParseTest.java
같은 일을 하는 함수 두개를 만들었다. domParseTest() 와 saxParseTest() 함수이다.
1. nyfeed.xml 파일을 읽어 파싱한다.
2. item 항목의 title 과 link 내용을 출력한다.
팁)
SAX 파싱 작업 중 더 이상 작업 할 필요가 없을 때는 SAXException 을 날려서 중단하면 된다.
참고 - http://www.ibm.com/developerworks/xml/library/x-tipsaxstop/
예) RSS 파일을 파싱하는 예
NY times 사이트의 RSS 링크 중 하나를 선택하여 nyfeed.xml 이라는 파일명으로 저장하였다.
RSS 항목들 중 item 항목에 대한 title 과 link 만 추려서 출력한다.
프로젝트 구조는 아래와 같다.
실행 결과는 아래와 같다.
DOM 파서
SAX 파서
nyfeed.xml
아래 링크로 접속하여 소스 보기 한 후 내용을 복사하여 프로젝트 폴더에 nyfeed.xml 파일로 저장
http://feeds.nytimes.com/nyt/rss/World
XMLParseTest.java
같은 일을 하는 함수 두개를 만들었다. domParseTest() 와 saxParseTest() 함수이다.
1. nyfeed.xml 파일을 읽어 파싱한다.
2. item 항목의 title 과 link 내용을 출력한다.
package xml.parse;
import java.io.File;
import javax.xml.parsers.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* XMLParserTest
*/
public class XMLParserTest {
private final String XML_FILE_PATH = "nyfeed.xml";
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
XMLParserTest xpt = new XMLParserTest();
xpt.domParseTest();
xpt.saxParseTest();
}
/**
*
* @throws Exception
*/
public void domParseTest() throws Exception {
System.out.println("==============================");
System.out.println("domParseTest()");
System.out.println("==============================");
File xmlFile = new File(XML_FILE_PATH);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFile);
doc.getDocumentElement().normalize();
System.out.printf("Root element:%s\n", doc.getDocumentElement().getNodeName());
NodeList itemNodeList = doc.getElementsByTagName("item");
for (int s = 0; s < itemNodeList.getLength(); s++) {
Node itemNode = itemNodeList.item(s);
if (itemNode.getNodeType() == Node.ELEMENT_NODE) {
Element itemElement = (Element)itemNode;
NodeList titleNodeList = itemElement.getElementsByTagName("title");
Element titleElement = (Element)titleNodeList.item(0);
NodeList childTitleNodeList = titleElement.getChildNodes();
System.out.printf("[title : %s]\n", ((Node)childTitleNodeList.item(0)).getNodeValue());
NodeList linkNodeList = itemElement.getElementsByTagName("link");
Element linkElement = (Element) linkNodeList.item(0);
NodeList childLinkNodeList = linkElement.getChildNodes();
System.out.printf("[link : %s]\n", ((Node)childLinkNodeList.item(0)).getNodeValue());
}
}
}
/**
*
* @throws Exception
*/
public void saxParseTest() throws Exception {
System.out.println("==============================");
System.out.println("saxParseTest()");
System.out.println("==============================");
File xmlFile = new File(XML_FILE_PATH);
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
DefaultHandler dh = new DefaultHandler() {
private boolean firstElement = true;
private boolean inItem = false;
private boolean inTitle = false;
private boolean inLink = false;
private StringBuilder characterSB;
@Override
public void startDocument() throws SAXException {
System.out.println("startDocument");
super.startDocument();
}
@Override
public void endDocument() throws SAXException {
System.out.println("endDocument");
super.endDocument();
}
@Override
public void startElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
if (firstElement) {
System.out.printf("Root element:%s\n", qName);
firstElement = false;
}
if (qName.equals("item")) {
inItem = true;
} else if (qName.equals("title")) {
inTitle = true;
} else if (qName.equals("link")) {
inLink = true;
}
if (inItem && (inTitle || inLink)) {
characterSB = new StringBuilder();
}
super.startElement(uri, localName, qName, attributes);
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (characterSB != null) {
characterSB.append(handleCharacters(ch, start, length));
}
super.characters(ch, start, length);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (characterSB != null) {
if (inItem && inTitle) {
System.out.printf("[title : %s]\n", characterSB.toString());
} else if (inItem && inLink) {
System.out.printf("[link : %s]\n", characterSB.toString());
}
characterSB = null;
}
if (qName.equals("item")) {
inItem = false;
} else if (qName.equals("title")) {
inTitle = false;
} else if (qName.equals("link")) {
inLink = false;
}
super.endElement(uri, localName, qName);
}
/**
*
* @param ch
* @param start
* @param end
* @return
*/
public String handleCharacters(char[] ch, int start, int length) {
StringBuilder sb = new StringBuilder();
for (int i = start; i < start + length; i++) {
sb.append(ch[i]);
}
return sb.toString();
}
};
parser.parse(xmlFile, dh);
}
}
팁)
SAX 파싱 작업 중 더 이상 작업 할 필요가 없을 때는 SAXException 을 날려서 중단하면 된다.
참고 - http://www.ibm.com/developerworks/xml/library/x-tipsaxstop/
(Tip: Stop a SAX parser when you have enough data)
throw new SAXException("Enough!");



댓글 없음:
댓글 쓰기