Java XML ContentHandler
2023. 1. 12. 12:58ㆍJava
프로젝트 내 src 내 xml 패키지 내 test02.dtd
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT 도서리스트 (책)* >
<!ELEMENT 책 (제목, 저자, 출판사, 가격, 이미지?, 소개?)> <!-- ?는 zero 나 one -->
<!ELEMENT 제목 (#PCDATA)>
<!ELEMENT 저자 (#PCDATA)>
<!ELEMENT 출판사 (#PCDATA)>
<!ELEMENT 가격 (#PCDATA)>
<!ELEMENT 이미지 EMPTY>
<!ELEMENT 소개 (#PCDATA)>
<!-- 속성 선언 -->
<!--
<!ATTLIST 책
id ID #IMPLIED
분류 CDATA #REQUIRED>
-->
<!-- 맨 마지막 XPath 검색예제용 -->
<!ATTLIST 책
분류 CDATA #REQUIRED
id CDATA #REQUIRED>
<!-- 요것은 생략이 가능하도록 IMPLIED로
경로를 나타내도록 src 추가 -->
<!ATTLIST 이미지
name ENTITY #IMPLIED
src CDATA #IMPLIED>
<!-- 이미지 이용하기때문에 노테이션 선언
헬퍼 프로그램은 익스플로러로 -->
<!NOTATION gif
PUBLIC "image/gif" "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe">
<!NOTATION jpg
PUBLIC "image/jpg" "C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe">
<!-- 외부 언파스드 엔티티 선언 -->
<!-- 외부 언파스드 엔티티(이미지) 선언 NDATA는 노테이션의 데이타라는 말 -->
<!ENTITY b1_img SYSTEM "img1.gif" NDATA gif>
<!ENTITY b2_img SYSTEM "img2.jpg" NDATA jpg>
<!ENTITY b3_img SYSTEM "img3.jpg" NDATA jpg>
<!-- 외부 파스드 엔티티 선언 -->
<!-- XML 파서가 해석할 수 있는 그러한 데이타 텍스트 파일, 이미지는 해석 못한다
파스드 엔티티는 노테이션 선언과 다르게 따로 NDATA 같이 적어줄 필요가 없구 -->
<!ENTITY b1_intro SYSTEM "b1.txt">
<!ENTITY b2_intro SYSTEM "b2.txt">
<!ENTITY b3_intro SYSTEM "b3.txt">
프로젝트 내 src 내 xml 패키지 내 test02.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--test02.dtd 파일 쓴 후 -->
<!DOCTYPE 도서리스트 SYSTEM "test02.dtd"><!-- id="book1"는 필요가 없다 -->
<도서리스트>
<!-- 마지막 XPath 검색예제 이전것 -->
<!--<책 분류="컴퓨터">-->
<책 분류="컴퓨터" id="book1"><!-- id추가후 XPathTest.java로 가기 -->
<제목>JAVA 프로그래밍</제목>
<저자>김말똥</저자>
<출판사>아이티 출판</출판사>
<가격>20000</가격>
<이미지 name="b1_img" /><!-- test02.dtd에 데이타가 EMPTY로 선언되었으므로 암것도 안씀 -->
<소개>&b1_intro;</소개>
</책>
<!--<책 분류="소설">-->
<책 분류="소설" id="book2">
<제목>삼국지</제목>
<저자>이문열</저자>
<출판사>역사 출판</출판사>
<가격>15000</가격>
<이미지 name="b2_img"/>
<소개>&b2_intro;</소개>
</책>
<!--<책 분류="컴퓨터">-->
<책 분류="컴퓨터" id="book3">
<제목>C언어</제목>
<저자>강길동</저자>
<출판사>터보 출판사</출판사>
<가격>15000</가격>
<이미지 name="b3_img"/>
<소개>&b3_intro;</소개>
</책>
</도서리스트>
프로젝트 내 src 내 java_xml 패키지 내 SaxCreate.java
package java_xml;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public class SaxCreate {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//SAX파서 공장 생성
SAXParserFactory saxFac = SAXParserFactory.newInstance();
// 밑에 요러한 것들을 기반으로 파싱을 하는데, 이런것들을 써서 파서속성을 정의한다
// DTD Validation : 디폴트는 유효성검사를 하지 않는다. false
// saxFac.setValidating(true) : 유효성검사를 하도록 설정
// 네임 스페이스를 해석
// saxFac.setNamespaceAware(true);
// XML schema Validation (필수적으로 Namespace 해석을 하도록 함)
// saxFac.setFeature("http://apache.org/xml/feature/schema", true);
//SAX 파서 생성
SAXParser parser = saxFac.newSAXParser();
XMLReader reader = parser.getXMLReader();
//DTDHandler 객체 생성
ContentHandler contentHandler = new MyContentH(); // 핸들러 객체화
// 핸들러객체를 생성후
// contentHandler를 등록하기 위해서 setContentHandler() 사용
// 이용해 SAX 파서에다가 컨텐트핸들러 객체인스턴스를 등록
reader.setContentHandler(contentHandler);
//파싱 지시
reader.parse("src/xml/test02.xml");
/*
* ContentHandler 인터페이스 주요 메소드 -> MyContentH.java 가 구현
* 프로세싱지시자,XML 문서의 엘리먼트들
* - startDocument() : XML 문서의 시작을 만났을 때 발생하는 이벤트를 처리하는 메소드
* - endDocument() : XML 문서의 끝을 만났을 때 발생하는 이벤트를 처리하는 메소드
* - startElement() : 엘리먼트의 시작태그를 만났을 때 발생하는 이벤트를 처리하는 메소드
* - stopElement() : 엘리먼트의 끝을 만났을 때 발생하는 이벤트를 처리하는 메소드
* - characters() : 문자 데이타를 만났을 때 발생하는 이벤트를 처리하는 메소드
* QName 엘리먼트 내의 이름,접두사하고 엘리먼트 네임이다
*
* public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
* localName은 접두사를 제외한 엘리먼트이름,QName 네임스페이스명이 있을경우 접두사를 포함한
* 엘리먼트의 이름을 의미. attributes는 속성정보이다.
*
* public void stopElement(String namespaceURI, String localName, String qName)
*
* public void characters(char[] ch, int start, int length)
* ch는 문서내용전체으캐릭터배열형태
*/
System.out.println("SAX 파서 생성 완료");
}
}
/*
* SAX Core 패키지의 주요 인터페이스와 클래스
* interface ContentHandler XML 문서 파싱도중에 마크업이나 문자데이타를 만났
* 을 때 호출되는 이벤트 핸들어의 인터페이스이다.
* INTERFACE DTDHandler: XML 문서 파싱도중에 DTD에 포함된 노테이션(=문자데이타가아닌그런것들의미) 선언이나
* 언파스드 엔티티 선언을 만났을 때 호출되는 이벤트 핸들어의 인터페이스이다.
* INTERFACE EnityResolver 외부 DTD 서브셋, 외부 파리미터 엔티티 참조, 내부 파스
* 드 파라미터 엔티티 참조 등을 만났을 때 호출되는 이벤트 핸들러의 인터페이스이다.
* INTERFACE XMLReader SAX 파서를 표현하는 인터페이스이다. SAX 파서의 작동
* 중에 호출될 이벤트 핸들러들을 등록하고, 파싱을 구동하는 데 필요한 메소드들을 정의하고있다.
*/
프로젝트 내 src 내 java_xml 패키지 내 MyContentH.java
package java_xml;
import org.xml.sax.*;
public class MyContentH implements ContentHandler{
public void setDocumentLocator (Locator locator) {}
public void startDocument() throws SAXException {
System.out.println("Start document");
}
public void endDocument() throws SAXException {
System.out.println("End document");
}
public void startPrefixMapping(String prefix, String uri) throws SAXException {}
public void endPrefixMapping(String prefix) throws SAXException {}
//시작 태그를 만났을 때 발생하는 이벤트를 처리하는 메소드
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
if(qName.equals("도서리스트")) {//도서리스트를 만나게되면
//qName은 접두사를 포함한 값 여기서는 해당 네임스페이스가 없어서 qName을
//프린트해준다
System.out.println(qName);
}else if (qName.equals("책")) {
System.out.println("------------< 도서 >------------");
System.out.println("분류 : "+atts.getValue("분류"));
}else {
// System.out.println(qName + ": ");
System.out.print(qName + ": ");
}
}// startElement
//끝 태그</아무개>를 만났을 때 (줄바꿈처리)이벤트를 처리하는 메소드
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println();
}
//문자 데이타를 만났을 때 발생하는 이벤트를 처리하는 메소드
public void characters(char[] ch, int start, int length) throws SAXException {
String content = new String(ch, start, length);
System.out.println(content);
}
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {}
public void processingInstruction(String target, String data) throws SAXException {}
public void skippedEntity(String name) throws SAXException {}
}
프로젝트 내 src 내 java_xml 패키지 내 SaxCreate.java 가 EUC-KR 로 디폴트 인코딩이 되어있으므로 콘솔창으 인코딩과 맞추기 위하여 SaxCreate.java 를 오른쪽 마우스를 클릭하여 Run As > Run Configurations... 에 가서 Common 탭에 가면
Encoding을 Other UTF-8 로 바꾸고
Apply
Run 으로 실행한다.
그러면 프로젝트 내 src 내 xml 패키지에 있는 b1.txt, b2.txt, b3.txt 의 내용이 함께 콘솔에 출력되지만,
프로젝트 내 src 내 xml 패키지에 있는 im1.gif, img2.jpg, img3.jpg 세 이미지는 MS EDGE 로 실행되어 나오지는
않는다. 파서가 외부 언파스드 엔티티들을 지나치는 것으로 보인다.
콘솔창에 다음과 같이 출력이 된다
Start document
도서리스트
------------< 도서 >------------
분류 : 컴퓨터
제목: JAVA 프로그래밍
저자: 김말똥
출판사: 아이티 출판
가격: 20000
이미지:
소개: 한국 엘리트 지식인 집단은 어떻게 탄생하는가 이 책은 미국 유학파 엘리트들이 학계와 기업에서 어떻게 헤게모니를 장
악하고, 그 기득권을 유지하는지를 탐색한다. 미국 유학파 엘리트가 한국과 미국 사이에 어떤 상황과 위치에 놓여 있는지를
분석하고, 그들의 독특한 정체성을 규명한다. 이를 통해 학벌사회의 최상위에 있는 한국 엘리트 지식인 집단이 어떻게 탄..
------------< 도서 >------------
분류 : 소설
제목: 삼국지
저자: 이문열
출판사: 역사 출판
가격: 15000
이미지:
소개: 딱 1그램의 용기면 충분해!긴급구호 현장에서, 오지여행길에서, 강의실과 도서관에서, 백두대간 길에서 평생 가슴 뛰는
삶, 쓸모 있는 삶이란 어떠한가를 온몸으로 증명해온 한비야. 누구보다 치열하게, 열정적으로 살아온 그녀는 지금, 인생 후반
전을 준비하기 위해 잠시 숨을 고르고 있다. 두려움, 외로움, 불안과는 거리가 멀어 보이는 한비야에게도 두려움이라는 ..
------------< 도서 >------------
분류 : 컴퓨터
제목: C언어
저자: 강길동
출판사: 터보 출판사
가격: 15000
이미지:
소개: 세계가 주목하는 차이나 파워의 실체를 파헤치다!『슈퍼차이나』는 KBS 특별기획 다큐멘터리 《슈퍼 차이나》를 단행
본으로 엮은 책으로, 슈퍼파워로 떠오른 중국의 부상을 인구, 기업, 경제, 군사, 땅, 문화, 공산당이라는 다양한 프레임을 통해
속속들이 보여준다. 이 책은 전 세계에 막대한 영향을 미치고 있는 중국의 현재 모습과 그 속에 숨은 야심과 전략을 적나..
End document
SAX 파서 생성 완료
그런데 b1.txt, b2.txt, b3.txt 가 출력될 때 첫번째 줄 다음에 하나의 공백줄이 더 출력이 왜 그렇게 되는건지는
모르겠다
'Java' 카테고리의 다른 글
Java XML setData(), setAttribute() (0) | 2023.01.12 |
---|---|
Java XML startElement(), characters(), endElement() (1) | 2023.01.12 |
Java XML TransformerFactory (0) | 2023.01.10 |
Java XML removeChild() (0) | 2023.01.09 |
Java XML setErrorHandler() (1) | 2023.01.09 |