반응형
출처: http://kr.blog.yahoo.com/kwon37xi/folder/3381246.html
Java와 XML 2판의 내용정리이다.
책을 보지 않으면 이 내용을 이해할 수 없을 수 있다.
Java와 XML 2판의 내용정리이다.
책을 보지 않으면 이 내용을 이해할 수 없을 수 있다.
SAX 파서는 XML 문서를 순차적으로 분서하는데 문서를 분석하는 동안 시작 태그나 속성, 종료 태그, 텍스트 데이터 등을 만나면 각 구성 요소를 처리하는 메소드를 호출한다.
이때 메소드를 호출하는 구성요소를 만나는 것이 이벤트가 된다. 즉, SAX 파서가 시작태그를 만나는 것이 하나의 이벤트이고 속성을 만나는 것이 또 다른 이벤트가 된다. 그리고 각 구성요소를 처리하는 메소드를 호출하는 것은 이벤트를 처리한다라고 표현하며, 호출되는 메소드를 콜백(callback) 메소드라고 부른다.
이때 메소드를 호출하는 구성요소를 만나는 것이 이벤트가 된다. 즉, SAX 파서가 시작태그를 만나는 것이 하나의 이벤트이고 속성을 만나는 것이 또 다른 이벤트가 된다. 그리고 각 구성요소를 처리하는 메소드를 호출하는 것은 이벤트를 처리한다라고 표현하며, 호출되는 메소드를 콜백(callback) 메소드라고 부른다.
SAX 클래스는 org.xml.sax 구조로 패키징되어 있다. 최소한 org.xml.sax.XMLReader 클래스가 있어야 한다.
SAX 공식 홈 : http://wwww.saxproject.org
SAXReader
SAX 사용의 시작은 org.xml.sax.XMLReader 의 객체를 얻는 것이다.// 파서 클래스 지정. 여기서는 아파치 Xerces private String parserClass="org.apache.xerces.parsers.SAXParser"; // 파싱에 사용할 XMLReader 객체 생성 XMLReader reader = XMLReaderFactory.createXMLReader(parserClass);
- XMLReader 의 객체는 재사용이 가능하지만 한 번에 한개의 XML 파일만을 파싱해야한다.
XML 문서 파싱
XMLReader 객체의 parse(InputSource) 혹은 parse(String URI)로 파싱한다. InputSource 사용권장.InputSource is = new InputSource(new FileInputStream(new File(xmlURI))); // 필수적으로 SystemID를 설정해야 한다. // SystemID는 XML 문서의 URI이다.(파일의 경우 파일의 경로) is.setSystemId(xmlURI); // 파싱 reader.parse(inputSource);
- 항상 시스템 ID를 설정해야만 한다!!
- SystemID는 XML문서의 URI이다. 파일의 경우는 파일의 경로를 의미한다.
Handler 등록
핸들러는 SAX 파서가 문서를 순차적으로 분석하는 동안 발생한 이벤트에 대해 호출할 메소드를을 가진 클래스 객체이다.- XMLReader.setContentHandler()
- XMLReader.setErrorHandler()
- XMLReader.setDTDHandler()
- XMLReader.setEntityHandler()
- 모든 핸들러는 throws SAXException 을 해야 한다.
Content Handler
- 요소 등 XML의 내용을 만났을때 호출되는 콜백 메소드를 가지는 클래스.
- ContentHandler 인터페이스 구현
public void setDocumentLocator(Locator locator)
- 분석중인 문서의 위치 정보를 가진 Locator의 객체 생성. Locator 객체의 getLineNumber(), getColumnNumber() 메소드들로 이벤트가 발생한 위치를 알아낼 수 있다.
- 이벤트의 위치는 실제 처리중인 분석과정에만 유효. Locator는 ContentHandler를 구현한 클래스 범위 내에서만 사용되어야 한다! Locator를 ContentHandler 의 인스턴스 멤버로 등록한다.
public void startDocument() throws SAXException
- 문서 시작시 호출되는 콜백 메소드.
- 모든 핸들러를 포함하여 가장 처음에 호출.(setDocumentLocator() 제외)
public void endDocument() throws SAXException
- 문서 분석이 끝날 때 호출되는 콜백 메소드
- 모든 핸들러를 포함하여 가장 나중에 호출.
public void processingInstruction(String target, String data)
- 처리지시어(<? --- ?>)를 처리한다.
- XML 데이터를 사용하는 실제 애플리케이션은 이 메소드로 처리 지시어를 받아 변수 값을 설정하거나 특정한 처리 과정을 수행하는 메소드를 실행한다.
- <?xml version="1.0"?> 이 부분은 전달되지 않는다.
네임스페이스 매핑
- 네임스페이스를 선언하는 xmlns 를 만나면 발생
- public void startPrefixMapping(String prefix, String uri)
- public void endPrefixMapping(String prefix)
- 프로그래밍 패턴
private Map namespaceMappings = new HashMap(); public void startPrefixMapping(String prefix, String uri) { // 시각적인 이벤트는 발생하지 않는다. namespaceMappings.put(uri, prefix); } public void endPrefixMapping(String prefix) { // 시각적인 이벤트는 발생하지 않는다. for (Iterator i = namespaceMappings.keySet().iterator(); i.hasNext(); ) { String uri = (String)i.next(); String thisPrefix = (String)namespaceMappings.get(uri); if (prefix.equals(thisPrefix)) { namespaceMappings.remove(uri); break; } } }
public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
- 요소가 시작될 때 호출
- qName 은 네임스페이스 접두어가 있다면 그것을 이름에 포함한다.
- atts 는 요소의 속성들을 배열로 가지고 있다.
public void endElement(String namespaceURI, String localName, String qName, Attributes atts)
- 요소가 닫힐 때 호출
public void characters(char[] ch, int start, int length)
- 요소의 텍스트 데이터
- ch 배열의 start 인덱스부터 length 길이 만큼 만이 데이터이다!!
public void ignorableWhitespace(char[] ch, int start, int length)
- 무시 가능한 공백문자가 올 경우 호출
- DTD나 스키마가 없으면 호출되지 않는다. DTD나 스키마에서 무시가능한 공백문자를 지정하기 때문이다.
public void skippedEntity(String name)
- 파서가 엔티티를 처리하지 않을 때 호출
- 실제 이 메소드가 호출되는 경우는 거의 없다.(Xerces는 절대 호출하지 않는다.)
- 이 콜백을 수행하면 엔티티 참조의 앞의 앰퍼샌드와 뒤의 세미콜론을 포함하지 않는 엔티티 참조를 매개변수로 전달한다.
ErrorHandler
- 파싱중 오류가 발생하면 호출되는 핸들러
- ErrorHandler 인터페이스 구현
public void warning(SAXParseException ex)
- 경고
public void error(SAXParseException ex)
- 치명적이지 않은 오류
public void fatalError(SAXParseException ex)
- 치명적 오류
- 파싱을 중지하는게 낫다.