XML SAX 구문 분석에 대한 자세한 설명

PHPz
풀어 주다: 2017-04-04 10:57:22
원래의
1716명이 탐색했습니다.



DOM과 SAX의 마지막 기능은 Java JavaScript와 같은 언어를 사용하여 xml 파일의 노드, 텍스트, 속성 및 기타 정보를 얻을 수 있도록 하는 것입니다.

이 글은 다른 블로그에서 인용한 내용입니다. 시간을 절약하기 위해 내용을 직접 복사했습니다. 일반적으로 JAVA, DOM 및 SAX에서 XML을 구문 분석하는 두 가지 방법이 있습니다. DOM은 W3C 표준이고 표준적인 구문 분석 방법을 제공하지만 DOM을 사용하여 XML을 구문 분석할 때 구문 분석기가 전체 문서를 읽고 메모리 상주 트리 구조(노드 트리)를 구축하기 때문에 구문 분석 효율성이 항상 만족스럽지 못했습니다. ), 그러면 코드에서 DOM의 표준 인터페이스를 사용하여 트리 구조를 조작할 수 있습니다. 그러나 대부분의 경우 전체 문서를 먼저 구문 분석하지 않고 문서의 일부에만 관심이 있으며 노드 트리의 루트 노드에서 필요한 데이터 중 일부를 인덱싱하는 것도 매우 시간이 많이 걸립니다.

SAX는 XML 구문 분석의 대안입니다. 문서 개체 모델 DOM에 비해 SAX는 XML 데이터를 읽고 조작하는 더 빠르고 가벼운 방법입니다. SAX를 사용하면 문서를 읽는 대로 처리할 수 있으므로 조치를 취하기 전에 전체 문서가 저장될 때까지 기다릴 필요가 없습니다. DOM에 필요한 오버헤드와 개념적 도약은 포함되지 않습니다. SAX API는 데이터 스트림 처리, 즉 데이터 흐름에 따라 순차적으로 데이터를 처리하는 데 적합한 이벤트 기반 API입니다. SAX API


는 문서를 구문 분석하는 동안 특정 이벤트가 발생할 때 이를 알려줍니다. 저장하지 않은 데이터는 응답 시 폐기됩니다.


다음은 SAX 구문 분석 XML의 예입니다(SAX 이벤트 처리의 모든 방법이 자세히 설명되어 있으므로 약간 깁니다). 처리를 위한 주요 인터페이스는 4개입니다. SAX API의 이벤트는 각각 ContentHandler, DTDHandler, EntityResolver 및 ErrorHandler입니다. 실제로 다음 예제는 약간 길 수 있습니다. DefaultHandler 클래스를 상속하고 일부 이벤트 처리 메서드를 재정의하면 이 예제의 효과를 얻을 수도 있습니다. 그러나 개요를 살펴보겠습니다. SAX API의 모든 주요 이벤트 구문 분석 방법을 살펴보세요. (실제로 DefaultHandler는 위의 4가지 이벤트 핸들러 인터페이스를 구현한 후 각 추상 메서드의 기본 구현을 제공합니다.)


1, ContentHandler 인터페이스: 문서 수신 Handler 인터페이스 논리적 내용에 대한 알림.

Java 코드 수집 코드

'import org.xml.sax.Attributes;

import org.xml.sax.ContentHandler;

import org. xml.sax.Locator;

import org.xml.sax.SAXException;

MyContentHandler 클래스가 ContentHandler를 구현함{

StringBuffer jsonStringBuffer;

int frontBlankCount = 0;

public MyContentHandler(){

jsonStringBuffer = new StringBuffer();

}

/*

* 문자 데이터 알림을 받습니다.

* DOM에서 ch[begin:end]는 Text 노드(nodeValue)의 노드 값과 동일합니다.

*/

@Override

공용 무효 문자(char[] ch, int start, int length)는 SAXException을 발생시킵니다. {

StringBuffer buffer = new StringBuffer();

for(int i = start ; i < 시작+길이 ; i++){

switch(ch[i]){

case '\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\':buffer.append("\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\");break;

케이스 '\\\\\\\\\\\\\ \\\\\\\\\ \\\\\\\\r':buffer.append("\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\r");break;

case '\\\\\\\\\\ \\\\\\\\\\\\\\\\\\n':buffer.append("\\\\\\ \\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");break;

케이스 ' \\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\t':buffer.append("\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\t ");break;

케이스 '\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\"':버퍼. 추가("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\"");break;

기본값 : buffer.append(ch[i]) ;

}

}

System.out.println(this.toBlankString(this.frontBlankCount) )+

">>> 문자("+length+"): "+buffer.toString());

}


/*

* 문서 끝 알림을 받습니다.

*/

@Override

public void endDocument()에서 SAXException이 발생합니다. {

System.out.println(this.toBlankString(--this. frontBlankCount)+

">>> 문서 종료");

}



/*

* 문서 종료 알림을 받습니다.

* 매개변수 의미는 다음과 같습니다.

* uri: 요소의 네임스페이스

* localName: 요소의 로컬 이름(접두사 없음)

* qName : 요소의 정규화된 이름(접두사 포함)

*

*/

@Override

public void endElement(String uri ,String localName,String qName )

은 SAXException {

System.out.println(this.toBlankString(--this.frontBlankCount)+

">>을 발생시킵니다. > 끝 요소: " +qName+"("+uri+")");

}


/*

* 끝 접두사 URI 범위의 매핑입니다.

*/

@Override

public void endPrefixMapping(String prefix)가 SAXException을 발생시킵니다. {

System.out.println(this.toBlankString(-- this.frontBlankCount)+

">>> end prefix_mapping : "+prefix);

}


/*

* 요소 콘텐츠에서 무시할 수 있는 공백에 대한 알림을 받습니다.

* 매개변수의 의미는 다음과 같습니다.

* ch: XML 문서의 문자

* start: 배열의 시작 위치

* 길이: 배열에서

*/

@Override

에서 읽은 문자 수 public void ignorableWhitespace(char[] ch, int start, int length)

SAXException 발생 {

StringBuffer 버퍼 = new StringBuffer();

for(int i = start ; i < start+length ; i++){

switch(ch [i]){

case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\ \\\\\\\\\\\\\\\\\\\\\\\\\\':buffer.append("\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\");break;

케이스 '\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\r' :buffer.append("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\r");break;

case '\\\\\\ \\\\\\\\\\\\ \\\\\\\\\\\\n':buffer.append("\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n") ;break;

case '\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\t':buffer.append( "\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\t");break;

case '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"':buffer.append("\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\"");break;

기본값: buffer.append(ch[i]);

}

}

System.out.println(this.toBlankString(this.frontBlankCount)+">> > 무시할 수 있는 공백("+length+"): "+buffer.toString());

}


/*

* 처리지시 통지를 받습니다.

* 매개변수 의미는 다음과 같습니다.

* target: 처리 명령 대상

* data: 처리 명령 데이터, 제공되지 않으면 null입니다.

*/

@Override

public void processInstruction(String target,String data)

throw SAXException {

System.out .println(this.toBlankString(this.frontBlankCount)+">>> 프로세스 명령: (대상 = \\\\\\\\\\\\\\\\\\\\\\\\ \ \\\\\\""

+대상+"\\\\\\\\\\\\\\\\\\\\\\\\\\\\",data = \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\""+데이터+"\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\")");

}


/*

* SAX 문서 이벤트의 출처를 찾는 데 사용되는 개체를 받습니다.

* 매개변수의 의미는 다음과 같습니다.

* 위치 지정자: SAX 문서 이벤트의 위치를 ​​반환할 수 있는 객체

*/

@Override

public void setDocumentLocator(Locator locator) {

System.out.println(this.toBlankString(this.frontBlankCount)+

">>> ; document_locator 설정: (lineNumber = " +locator.getLineNumber()

+", columnNumber = "+locator.getColumnNumber()

+", systemId = "+locator.getSystemId()

+" ,publicId = "+locator.getPublicId()+")");


}


/*

* 건너뛴 항목에 대한 알림을 받습니다.

* 매개변수 의미는 다음과 같습니다.

* name: 건너뛰는 엔터티의 이름입니다. 매개변수 엔터티인 경우 이름은 '%'로 시작됩니다.

* 외부 DTD 하위 집합인 경우 "[dtd]" 문자열이 됩니다.

*/

@Override

public void skipedEntity(String name ) SAXException 발생 {

System.out.println(this.toBlankString(this.frontBlankCount)+

">>> skiped_entity : "+name);

}


/*

* 문서 시작 알림을 받습니다.

*/

@Override

public void startDocument()에서 SAXException이 발생합니다. {

System.out.println(this.toBlankString(this.frontBlankCount++) +

">>> 문서 시작 ");

}


/*

* 요소 시작 알림을 받습니다.

* 매개변수 의미는 다음과 같습니다.

* uri: 요소의 네임스페이스

* localName: 요소의 로컬 이름(접두사 없음)

* qName : 요소의 정규화된 이름(접두사 포함)

* atts : 요소의 속성 컬렉션

*/

@Override

public void startElement(String uri , String localName, String qName,

Attributes atts) throws SAXException {

System.out.println(this.toBlankString(this.frontBlankCount++)+

">> ;> 시작 요소: "+qName+"("+uri+")");

}


/*

* 접두사 URI 네임스페이스 범위 매핑을 시작합니다.

* 이 이벤트에 대한 정보는 일반 네임스페이스 처리에 필요하지 않습니다.

* http://xml.org/sax/features/namespaces 기능이 true(기본값)인 경우

* SAX XML 리더는 요소 및 속성 이름의 접두사를 자동으로 대체합니다.

* 매개변수 의미는 다음과 같습니다.

* prefix: prefix

* uri: 네임스페이스

*/

@Override

public void startPrefixMapping(String prefix,String uri)

throws SAXException {

System.out.println(this.toBlankString(this.frontBlankCount++)+

">>> prefix_mapping 시작 : xmlns:"+prefix+" = "

+"\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\""+uri+"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"");


}


private String toBlankString(int count){

StringBuffer 버퍼 = 새로운 StringBuffer ( );

for(int i = 0;i

buffer.append(" " ");

return buffer.toString();

}


}'



2, DTDHandler 인터페이스: 수신 및 관련 이벤트에 대한 DTD 알림 처리기 인터페이스

'import org.xml.sax.DTDHandler;

import org.xml.sax.SAXException ;


공용 클래스 MyDTDHandler는 DTDHandler를 구현합니다. {


/*

* 주석 선언 이벤트 알림 수신 .

* 매개변수의 의미는 다음과 같습니다.

* name - 주석의 이름. publicId - 주석의 공개 식별자 또는 제공되지 않은 경우 null입니다. 🎜>* systemId - 주석의 시스템 식별자 또는 제공되지 않은 경우 null

*/

@Override

public void notationDecl(String name. , String publicId, String systemId)

throw SAXException {

System.out.println(">>> 표기법 선언: (name = "+name

+",systemId = "+publicId

+",publicId = "+systemId+")");

}

/ *

* 해결되지 않은 엔터티 선언 이벤트에 대한 알림을 받습니다.


* 매개변수의 의미는 다음과 같습니다.

* name - 해결되지 않은 엔터티의 이름입니다.

* publicId - 엔터티의 공개 식별자이거나 제공되지 않은 경우 null입니다.

* systemId - 엔터티의 시스템 식별자입니다.

* notationName - 관련 주석의 이름입니다.

*/

@Override

public void unparsedEntityDecl(String name,

String publicId,

String systemId,

String notationName)은 SAXException을 발생시킵니다. {

System.out.println(">>> 구문 분석되지 않은 엔터티 선언: (name = "+name

+",systemId = " +publicId

+",publicId = "+systemId

+",notationName = "+notationName+")");

}

}'


3. EntityResolver 인터페이스: 엔터티를 구문 분석하기 위한 기본 인터페이스입니다.

Java 코드 수집 코드


'import java.io.IOException;

import org.xml.sax.EntityResolver;

import org.xml.sax.InputSource;


import org.xml.sax.SAXException;

공용 클래스 MyEntityResolver는 EntityResolver를 구현합니다. {


/*

* 애플리케이션이 외부 엔터티를 확인할 수 있도록 허용합니다.


* 파서는 외부 엔터티(최상위 문서 엔터티 제외)를 열기 전에 이 메서드를 호출합니다.

* 매개변수 의미는 다음과 같습니다.

* publicId: the 참조된 외부 엔터티 공용 식별자이거나 제공되지 않은 경우 null입니다.

* systemId: 참조된 외부 엔터티의 시스템 식별자입니다.

* 반환값:

* 새 입력 소스를 설명하는 InputSource 객체 또는 null,

* 파서에게 시스템 식별자에 대한 일반 URI 연결을 열도록 요청합니다.

*/

@Override

public InputSourcesolveEntity(String publicId, String systemId)

throws SAXException, IOException {

return null;

}


}


4, ErrorHandler 인터페이스: 오류 처리기 기본입니다. 인터페이스.

Java 코드 수집 코드

import org.xml.sax.ErrorHandler;

import org.xml.sax.SAXException;

import org.xml .sax.SAXParseException;


공개 클래스 MyErrorHandler는 ErrorHandler를 구현합니다. {


/*

* 복구 가능한 오류 알림 받기

*/

@Override

public void error(SAXParseException e) throws SAXException {

System.err.println(" 오류("+e.getLineNumber()+","

+e.getColumnNumber()+") : "+e.getMessage());

}


/*

* 복구할 수 없는 오류에 대한 알림을 받습니다.

*/

@Override

public void fatalError(SAXParseException e) throws SAXException {

System.err.println("FatalError ("+e .getLineNumber()+","

+e.getColumnNumber()+") : "+e.getMessage());

}


/*

* 복구할 수 없는 오류에 대한 알림을 받습니다.

*/

@Override

공개 무효 경고(SAXParseException e)가 SAXException을 발생시킵니다. {

System.err.println("경고("+e .getLineNumber()+","

+e.getColumnNumber()+") : "+e.getMessage());

}


}



Test 클래스의 주요 메소드는 books.xml을 구문 분석할 때 이벤트 정보를 인쇄합니다.

Java 코드 수집 코드

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;


import org.xml.sax.ContentHandler;

import org.xml.sax.DTDHandler;

import org.xml.sax .EntityResolver;

import org.xml.sax.ErrorHandler;

import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

org.xml.sax.XMLReader 가져오기;

org.xml.sax.helpers.XMLReaderFactory 가져오기;



공용 클래스 테스트 {


public static void main(String[] args) throws SAXException,

FileNotFoundException, IOException {

//문서 콘텐츠 관련 이벤트 처리를 위한 핸들러 생성

ContentHandler contentHandler = new MyContentHandler();

//오류 이벤트 처리를 위한 핸들러 생성

ErrorHandler errorHandler = new MyErrorHandler();

//DTD 관련 이벤트를 처리하는 핸들러 생성

DTDHandler dtdHandler = new MyDTDHandler();

//엔티티 파서 생성

EntityResolver 엔터티Resolver = new MyEntityResolver();


//XML 파서 생성(SAX를 통해 XML 읽기 및 구문 분석)

XMLReader 리더 = XMLReaderFactory.createXMLReader();

/*

* 파서 관련 기능 설정

* http://xml.org/sax/features/validation = true 확인 기능이 활성화되었습니다.

* http://xml.org/sax/features/namespaces = true는 독자에게 네임스페이스 기능이 활성화되었음을 나타냅니다

*/

. setFeature(" http://xml.org/sax/features/validation",true);

reader.setFeature("http://xml.org/sax/features/namespaces",true);

//문서 콘텐츠 관련 이벤트 처리를 위한 XML 파서 핸들러 설정

reader.setContentHandler(contentHandler);

//오류 이벤트 처리를 위한 XML 파서 핸들러 설정

reader.setErrorHandler(errorHandler);

//DTD 관련 이벤트를 처리하도록 XML 파서의 핸들러 설정

reader.setDTDHandler(dtdHandler);

//XML 파서의 엔터티 파서 설정

reader.setEntityResolver(entityResolver);

//books.xml 문서 파싱

reader.parse(new InputSource( new FileReader("books.xml")));

}


}'



books.xml 파일의 내용은 다음과 같습니다.


Xml 코드 수집코드







JAVA로 생각하기




핵심 JAVA2




C++ 입문서




콘솔 출력은 다음과 같습니다.


>>> systemId = null, publicId = null)

>>> 문서 시작

오류(2,7): 문서가 잘못되었습니다. 문법이 없습니다.

오류 (2,7): 문서 루트 요소 "books"는 DOCTYPE 루트 "null"과 일치해야 합니다.

>>>

> >> 시작 요소: books(http://test.org/books)

>>> 문자(2): \\\\\\ \\\\\\\\ \\\\\\\\\\\\\\\\\N\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\t

>>> 문자(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> 시작 요소 : book(http://test.org/books)

>>> 문자(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\티\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t

>>> 시작 요소 : 이름(http://test.org/books)

>>> 문자(16): JAVA로 생각하기

>>> 끝 요소 : 이름(http://test.org/books)

>>> 문자(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> 끝 요소 : 책(http://test.org/books)

>>> 문자(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> 시작 요소 : book(http://test.org/books)

>>> 문자(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\티\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t

>>> 시작 요소 : 이름(http://test.org/books)

>>> 문자(10): Core JAVA2

>>> 끝 요소 : 이름(http://test.org/books)

>>> 문자(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> 끝 요소 : 책(http://test.org/books)

>>> 문자(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> 시작 요소 : book(http://test.org/books)

>>> 문자(3): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\티\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\t

>>> 시작 요소 : 이름(http://test.org/books)

>>> 문자(10): C++ 입문서

>>> 끝 요소 : 이름(http://test.org/books)

>>> 문자(2): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\t

>>> 끝 요소 : 책(http://test.org/books)

>>> 문자(1): \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n

>>> 끝 요소 : books(http://test.org/books)

>>> end prefix_mapping :

>>> 문서 종료  

위 내용은 XML SAX 구문 분석에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!