- 다음 자료는 SDS 온라인 강의 자료를 기초로 작성하였습니다. 이전에 XML 관련 파싱 프로그램 개발시에는 라이브러리를 가져다 쓰기만해서 코드에 대한 이해도가 많이 떨어졌었는데, 공부를 통해서 정리를 하니 XML 관련한 코드 개
발시에 많이 도움이 될듯 하네요. 역시 프로그래밍에는 많이 공부한 사람이 잘하게 되어 있는 것 같네요. :-)
알아보고 구현 방법을 알아본다.
때마다 이벤트를 발생한다. 각 이벤트가 발생할 때마다 등록된 핸들러의 정해진 메소드들이
호출되는 방법으로 문서를 처리 한다.
구현 순서는 다음과 같다.
1. 목적에 맞는 이벤트를 처리할 핸들러 메소드들을 작성한다.
2. SAX 객체를 생성한다.
3. 생성된 SAX 객체와 핸들러 객체를 통해 XML 문서를 읽어 들인다.
SAX의 핵심으로, 일반적인 문서 이벤트를 처리한다. 문서의 시작, 요소의 시작과 끝, 요소가
포함하는 내용의 문자를 만날 때 호출된다.
+ void characters(char[] ch, int start, int length)
문자데이터가 인식되면 호출된다.
+ void endDocument()
문서의 끝이 인식되면 호출된다.
+ void endElement(String namespaceURI, String localName, String qName)
요소의 종료가 인식되면 호출된다.
+ void endPrefixMapping(String prefix)
prefix-URI 이름 공간의 종료가 인식되면 호출된다.
+ void ignorableWhitespace(char[] ch, int start, int length)
요소 내용에서 무시 가능한 공백이 인식되면 호출된다.
+ void processingInstruction(String target, String data)
PI가 인식되면 호출된다.
+ void setDocumentLocator(Locator locator)
이벤트가 발생된 위치 정보를 알려 주는 객체 전달 시 호출된다.
+ void skippedEntity(String name)
스킵된 엔티티가 인식되면 호출된다.
+ void startDocument()
문서의 시작이 인식되면 호출된다.
+ void startElement(String namespaceURI, String localName, String qName, Attributes atts)
요소의 시작이 인식되면 호출된다.
+ void startPrefixMapping(String prefix, String uri)
prefix-URI 이름 공간의 시작이 인식되면 호출된다.
- org.xml.sax.DTDHandler
기본적인 파싱에 있어 요구되는 DTD 이벤트를 핸들링하기 위해 호출된다. 즉 표기법과 파싱되지
않는 엔티티(entity)선언을 만날 때 호출 된다.
+ void notationDecl(String name, String pulbicId, String systemId)
DTD 선언 이벤트가 인식되면 호출된다.
+ void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
파싱되지 않는 엔티티 선언 이벤트가 인식되면 호출된다.
- org.xml.sax.EntityResolver
외부 엔티티를 참조하기 위하여 호출된다. 만일 문서에 외부 엔티티 참조가 없다면, 이 인터페이스는
필요 없다.
+ InputSource resolveEntity(String publicId, String systemId)
확장 엔티티 처리와 관련된 기능을 처리한다.
- org.xml.sax.ErrorHandler
에러를 처리하기 위해 사용된다. 파서는 모든 경고와 에러를 처리하기 위해 이 핸들러를 사용한다.
+ void error(SAXParseException exception)
복구 가능한 오류 발생시 호출된다.
+ void fatalError(SAXParseException exception)
복구 불가능한 오류 발생시 호출된다.
+ void warning(SAXParseException exception)
경고 오류 발생시 호출된다.
오버라이드 구현하기에는 많은 일이 필요하게 된다.
그래서 불필요한 메소드에 대한 구현 할 필요 없도록 하나의 클래스에 모든
인터페이스를 상속해 필요한 메소드만 구현 할 수 있도록 하나의 클래스를
만들었으며 클래스명은 다음과 같다.
org.xml.sax.helpers.DefaultHandler
위 클래스를 이용해 자신에게 필요한 메소드만 오버라이드 하면 된다.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXHandlerSample {
/**
* @param args
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
* @throws FileNotFoundException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, FileNotFoundException, IOException {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
// Create handler
SampleHandler handler = new SampleHandler();
sp.parse(new FileInputStream("C:\\DEV\\workspace\\ws01\\Java2XML\\src\\Sample.xml"), handler);
}
}
class SampleHandler extends DefaultHandler {
StringBuffer sb = new StringBuffer();
boolean isPrint = false;
@Override
public void startDocument() throws SAXException {
System.out.println("Start XML Document");
}
@Override
public void endDocument() throws SAXException {
System.out.println("End XML Document");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("Start : " + qName);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("End : " + qName);
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String str = new String(ch, start, length);
if (str.trim().length() != 0) {
System.out.println(str);
}
}
}
- Sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Child>Child 01</Child>
<Child>Child 02</Child>
</Root>
Start : Root
Start : Child
Child 01
End : Child
Start : Child
Child 02
End : Child
End : Root
End XML Document
발시에 많이 도움이 될듯 하네요. 역시 프로그래밍에는 많이 공부한 사람이 잘하게 되어 있는 것 같네요. :-)
- 목 적
알아보고 구현 방법을 알아본다.
- SAX에 대해서
때마다 이벤트를 발생한다. 각 이벤트가 발생할 때마다 등록된 핸들러의 정해진 메소드들이
호출되는 방법으로 문서를 처리 한다.
구현 순서는 다음과 같다.
1. 목적에 맞는 이벤트를 처리할 핸들러 메소드들을 작성한다.
2. SAX 객체를 생성한다.
3. 생성된 SAX 객체와 핸들러 객체를 통해 XML 문서를 읽어 들인다.
- 핸들러(인터페이스)별 메소드 설명
SAX의 핵심으로, 일반적인 문서 이벤트를 처리한다. 문서의 시작, 요소의 시작과 끝, 요소가
포함하는 내용의 문자를 만날 때 호출된다.
+ void characters(char[] ch, int start, int length)
문자데이터가 인식되면 호출된다.
+ void endDocument()
문서의 끝이 인식되면 호출된다.
+ void endElement(String namespaceURI, String localName, String qName)
요소의 종료가 인식되면 호출된다.
+ void endPrefixMapping(String prefix)
prefix-URI 이름 공간의 종료가 인식되면 호출된다.
+ void ignorableWhitespace(char[] ch, int start, int length)
요소 내용에서 무시 가능한 공백이 인식되면 호출된다.
+ void processingInstruction(String target, String data)
PI가 인식되면 호출된다.
+ void setDocumentLocator(Locator locator)
이벤트가 발생된 위치 정보를 알려 주는 객체 전달 시 호출된다.
+ void skippedEntity(String name)
스킵된 엔티티가 인식되면 호출된다.
+ void startDocument()
문서의 시작이 인식되면 호출된다.
+ void startElement(String namespaceURI, String localName, String qName, Attributes atts)
요소의 시작이 인식되면 호출된다.
+ void startPrefixMapping(String prefix, String uri)
prefix-URI 이름 공간의 시작이 인식되면 호출된다.
- org.xml.sax.DTDHandler
기본적인 파싱에 있어 요구되는 DTD 이벤트를 핸들링하기 위해 호출된다. 즉 표기법과 파싱되지
않는 엔티티(entity)선언을 만날 때 호출 된다.
+ void notationDecl(String name, String pulbicId, String systemId)
DTD 선언 이벤트가 인식되면 호출된다.
+ void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
파싱되지 않는 엔티티 선언 이벤트가 인식되면 호출된다.
- org.xml.sax.EntityResolver
외부 엔티티를 참조하기 위하여 호출된다. 만일 문서에 외부 엔티티 참조가 없다면, 이 인터페이스는
필요 없다.
+ InputSource resolveEntity(String publicId, String systemId)
확장 엔티티 처리와 관련된 기능을 처리한다.
- org.xml.sax.ErrorHandler
에러를 처리하기 위해 사용된다. 파서는 모든 경고와 에러를 처리하기 위해 이 핸들러를 사용한다.
+ void error(SAXParseException exception)
복구 가능한 오류 발생시 호출된다.
+ void fatalError(SAXParseException exception)
복구 불가능한 오류 발생시 호출된다.
+ void warning(SAXParseException exception)
경고 오류 발생시 호출된다.
- 핸들러(인터페이스)의 구현 최소화
오버라이드 구현하기에는 많은 일이 필요하게 된다.
그래서 불필요한 메소드에 대한 구현 할 필요 없도록 하나의 클래스에 모든
인터페이스를 상속해 필요한 메소드만 구현 할 수 있도록 하나의 클래스를
만들었으며 클래스명은 다음과 같다.
org.xml.sax.helpers.DefaultHandler
위 클래스를 이용해 자신에게 필요한 메소드만 오버라이드 하면 된다.
- Sample code
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXHandlerSample {
/**
* @param args
* @throws SAXException
* @throws ParserConfigurationException
* @throws IOException
* @throws FileNotFoundException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, FileNotFoundException, IOException {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
// Create handler
SampleHandler handler = new SampleHandler();
sp.parse(new FileInputStream("C:\\DEV\\workspace\\ws01\\Java2XML\\src\\Sample.xml"), handler);
}
}
class SampleHandler extends DefaultHandler {
StringBuffer sb = new StringBuffer();
boolean isPrint = false;
@Override
public void startDocument() throws SAXException {
System.out.println("Start XML Document");
}
@Override
public void endDocument() throws SAXException {
System.out.println("End XML Document");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("Start : " + qName);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("End : " + qName);
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
String str = new String(ch, start, length);
if (str.trim().length() != 0) {
System.out.println(str);
}
}
}
- Sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Child>Child 01</Child>
<Child>Child 02</Child>
</Root>
- 실행시 결과 화면
Start : Root
Start : Child
Child 01
End : Child
Start : Child
Child 02
End : Child
End : Root
End XML Document