SAX와 DOM의 차이점은 무엇입니까?


242

XML 파서 에 대한 기사를 읽고 SAXDOM을 발견했습니다 .

SAX 는 이벤트 기반이며 DOM 은 트리 모델입니다. 이러한 개념의 차이점을 이해하지 못합니다.

내가 이해 한 바에 따르면, 이벤트 기반은 어떤 종류의 이벤트가 노드에 발생 함을 의미합니다. 특정 노드를 클릭 할 때와 같이 모든 노드를 동시에로드하는 대신 모든 하위 노드를 제공합니다. 그러나 DOM 파싱 의 경우 모든 노드를로드하고 트리 모델을 만듭니다.

이해가 정확합니까?

내가 틀렸다면 저를 수정하거나 이벤트 기반 및 트리 모델을 더 간단한 방법으로 설명하십시오.


DOM을 올바르게 말하는 것은 파서가 아닙니다. 주어진 DOM 기반 소프트웨어는 마크 업 구문 분석을 포함하거나 포함하지 않을 수 있으며 대부분의 HTML DOM 소프트웨어는이를 수행합니다. 그러나 DOM은 직렬화 형식과 전혀 관련이없는 완전히 분리 된 것입니다.
Bob77

답변:


305

글쎄, 당신은 가까이 있습니다.

SAX에서 XML이 구문 분석 될 때 이벤트가 트리거됩니다 . 파서가 XML을 구문 분석 할 때 태그 시작 (예 <something>:)이 발생하면 tagStarted이벤트를 트리거합니다 (실제 이벤트 이름이 다를 수 있음). 마찬가지로 구문 분석 ( </something>) 하는 동안 태그의 끝에 도달하면 태그가 트리거됩니다 tagEnded. SAX 구문 분석기를 사용하면 이러한 이벤트를 처리하고 각 이벤트와 함께 리턴 된 데이터를 이해해야합니다.

DOM에서는 구문 분석 중에 트리거 된 이벤트가 없습니다. 전체 XML이 구문 분석되고 XML의 노드 중 DOM 트리가 생성되어 리턴됩니다. 구문 분석되면 사용자는 트리를 탐색하여 XML의 다양한 노드에 미리 포함 된 다양한 데이터에 액세스 할 수 있습니다.

일반적으로 DOM은 사용하기 쉽지만 XML을 사용하기 전에 전체 XML을 구문 분석하는 오버 헤드가 있습니다.


135
+1-명확히하기 위해 : RAM에 맞는 더 작은 파일을 가진 DOM 파서를 사용하십시오. 큰 파일에는 SAX 파서를 사용하십시오.
Richard H

감사합니다 @ spartkymat. 그러나 SAX 이벤트 기반의 경우 SAX 파서는 특정 자식 노드가 특정 부모의 자식인지 알 수 있습니까? 아니면 단순히 파싱됩니까? 예를 들어. <회사>가 있고 자녀가 <직원>입니다. 따라서이 경우 해당 회사와 직원은 파싱되거나 회사가 직원의 부모라는 관계를 보여 줍니까?
user414967

4
파싱 ​​만됩니다. 그러한 정보는 상태 머신 등을 통해 직접 유지 관리해야합니다. DOM 파서를 사용해야하는 더 많은 이유 (자원이 허용되는 경우) :-).
sparkymat

1
@Richard H XML 파일을 너무 많이 사용하여 RAM에 맞지 않는 사람은 매우 잘못된 일을하고 있다고 주장합니다.
Antred

1
40m 크기의 Excel을로드하고 SAX 파서를 사용할 때 200m 메모리를 사용하지만 DOM 파서를 사용할 때는 9g 메모리를 사용하십시오.
zhiyuan_

98

몇 마디로 ...

SAX ( S imple 대한 PI X ㎖) : 스트림 - 기반 프로세서이다. 당신은 언제라도 메모리에 아주 작은 부분만을 가지고 있으며 등의 이벤트에 콜백 코드를 구현하여 XML 스트림을 "스니핑"합니다 . 메모리를 거의 사용하지 않지만 xpath 나 traverse와 같은 "DOM"작업은 수행 할 수 없습니다 나무.tagStarted()

DOM ( D ocument O bject M ODEL) : 당신은 메모리에 전부로드 - 그것은 거대한 메모리 돼지입니다. 중간 크기의 문서라도 메모리를 날릴 수 있습니다. 그러나 xpath를 사용하고 트리 등을 통과 할 수 있습니다.


66

더 간단한 말로 여기에 :

DOM

  • 트리 모델 파서 (Object based) (Tree of node).

  • DOM은 파일을 메모리에로드 한 다음 파일을 구문 분석합니다.

  • 구문 분석하기 전에 전체 XML 파일을로드하므로 메모리 제한이 있습니다.

  • DOM을 읽고 쓸 수 있습니다 (노드 삽입 또는 삭제 가능).

  • XML 컨텐츠가 작 으면 DOM 구문 분석기를 선호하십시오.

  • 태그를 검색하고 태그 내부의 정보를 평가하기 위해 뒤로 및 앞으로 검색이 가능합니다. 따라서 탐색이 쉬워집니다.

  • 런타임에 느려집니다.

색소폰

  • 이벤트 기반 파서 (이벤트 순서).

  • SAX는 파일을 읽을 때 파일을 구문 분석합니다 (예 : 노드별로 구문 분석).

  • 메모리에 XML 내용을 저장하지 않으므로 메모리 제한이 없습니다.

  • SAX는 읽기 전용입니다. 즉, 노드를 삽입하거나 삭제할 수 없습니다.

  • 메모리 내용이 큰 경우 SAX 파서를 사용하십시오.

  • SAX는 XML 파일을 위에서 아래로 읽으며 뒤로 탐색 할 수 없습니다.

  • 런타임에 더 빠릅니다.


완벽 ... 포인트에 대한 답변을 기대했다. 좋은 일 :)
Kunal Gupta

37

DOM 기반 모델에 대한 이해가 정확합니다. XML 파일은 전체로로드되며 모든 내용은 문서가 나타내는 트리의 메모리 내 표현으로 작성됩니다. 입력 파일의 크기에 따라 시간과 메모리가 많이 소모 될 수 있습니다. 이 방법의 장점은 문서의 모든 부분을 쉽게 쿼리 할 수 ​​있고 트리의 모든 노드를 자유롭게 조작 할 수 있다는 것입니다.

DOM 방식은 일반적으로로드 된 후 다른 방식으로 수정 및 쿼리해야 할 수있는 작은 XML 구조 (작은 플랫폼의 마력 및 메모리 용량에 따라 달라짐)에 사용됩니다.

반면에 SAX는 거의 모든 크기의 XML 입력을 처리하도록 설계되었습니다. SAX는 문서의 구조를 파악하고 모든 노드, 속성 등에 대해 잠재적으로 많은 수의 객체를 준비하는 데있어 XML 프레임 워크 대신 많은 노력을 기울이고 있지만 SAX는이를 완전히 남겨두고 있습니다.

기본적으로 상단에서 입력을 읽고 특정 "이벤트"가 발생할 때 제공하는 콜백 메소드를 호출합니다. 이벤트가 여는 태그, 태그의 속성, 요소 내부에서 텍스트를 찾거나 끝 태그를 발견 할 수 있습니다.

SAX는 완고하게 입력을 읽고이 방식으로 무엇을 보는지 알려줍니다. 필요한 모든 주 정보를 유지하는 것은 귀하의 책임입니다. 일반적으로 이것은 일종의 상태 머신을 구축한다는 의미입니다.

XML 처리에 대한이 접근 방식은 훨씬 더 지루하지만, 매우 강력 할 수도 있습니다. 블로그 피드에서 뉴스 기사의 제목을 추출한다고 가정 해보십시오. DOM을 사용하여이 XML을 읽으면 XML에 포함 된 모든 기사 내용, 모든 이미지 등을 관심이없는 경우에도 메모리에로드합니다.

SAX를 사용하면 "startTag"이벤트 메서드가 호출 될 때마다 요소 이름이 "title"인지 확인할 수 있습니다. 그렇다면 다음 "elementText"이벤트가 제공하는 것을 추가해야한다는 것을 알고 있습니다. "endTag"이벤트 호출을 받으면 "title"의 닫는 요소인지 다시 확인하십시오. 그 후, 입력이 끝나거나 이름이 "title"인 다른 "startTag"가 나타날 때까지 모든 추가 요소를 무시합니다. 등등...

이 방법으로 메가 바이트와 메가 바이트의 XML을 읽을 수 있으며 필요한 양의 데이터 만 추출하면됩니다.

물론이 접근 방식의 단점은 추출해야하는 데이터와 XML 구조가 얼마나 복잡한 지에 따라 더 많은 장부 관리를 수행해야한다는 것입니다. 또한 XML 트리의 구조를 전체적으로 다룰 수 없기 때문에 자연스럽게 XML 트리의 구조를 수정할 수 없습니다.

따라서 일반적으로 SAX는 잠재적 인 대량의 데이터를 특정 "쿼리"를 염두에두고 조합하는 데 적합하지만 수정할 필요는 없지만 DOM은 구조와 내용을 변경하는 데있어 모든 유연성을 제공하면서 더 많은 비용을 들이지 않고 있습니다. 더 높은 자원 수요.


16

사과와 배를 비교하고 있습니다. SAX는 직렬화 된 DOM 구조를 구문 분석 하는 구문 분석기 입니다. 많은 다른 파서가 있으며 "이벤트 기반"은 구문 분석 방법을 나타냅니다.

어쩌면 작은 요약이 순서대로 있습니다.

  • 문서 객체 모델 (DOM)은 계층 적 트리 기반의 문서 구조를 기술하는 추상적 데이터 모델이고; 문서 트리는 노드 , 즉 요소, 속성 및 텍스트 노드 (및 기타 노드)로 구성됩니다. 노드에는 부모, 형제 자매 및 자녀가 있으며 JavaScript 등을 사용하는 데 익숙한 모든 것을 통과 할 수 있습니다 (실수로 DOM과 관련이 없음).

  • HTML 또는 XML과 같은 마크 업 언어를 사용하여 DOM 구조를 직렬화 (즉, 파일에 기록) 할 수 있습니다 . HTML 또는 XML 파일에는 추상 문서 트리의 "작성된"또는 "평평한"버전이 포함됩니다.

  • 컴퓨터가 파일에서 DOM 트리를 조작하거나 표시 하려면 파일 을 직렬화 해제 하거나 파싱 하여 추상 트리를 메모리에 재구성해야합니다. 이것은 파싱이 오는 곳입니다.

이제 파서의 본질에 도달했습니다. 구문 분석하는 한 가지 방법은 전체 문서를 읽고 메모리에 트리 구조를 재귀 적으로 작성하고 최종 결과를 사용자에게 공개하는 것입니다. (이 파서를 "DOM 파서"라고 부를 수 있다고 가정합니다.) 사용자에게는 매우 유용 할 것입니다 (PHP의 XML 파서가하는 것 같습니다).

반면, SAX에서 수행 한 이벤트 기반 구문 분석은 파일을 선형으로보고 "이 요소가 시작되었습니다"와 같은 구조적 데이터가 발견 될 때마다 사용자에게 콜백 을합니다. , "여기에 일부 텍스트"등이 있습니다. 이는 입력 파일 크기에 대한 염려없이 영원히 지속될 수 있다는 이점이 있지만, 사용자가 모든 실제 처리 작업을 수행해야하기 때문에 훨씬 더 낮은 수준입니다. 콜백). 원래 질문으로 돌아 가기 위해 "이벤트 기반"이라는 용어 는 파서가 XML 파일을 통과 할 때 발생 하는 구문 분석 이벤트 를 말합니다 .

위키 백과 문서는 SAX 구문 분석의 단계에 많은 세부 사항이있다.


11

이 질문에 대한 일반적인 Q & A 지향 답변을 제공합니다.

질문에 대한 답변

왜 XML 파서가 필요합니까?

우리는 XML 파서가 필요하다. 우리는 애플리케이션에서 모든 것을 처음부터하고 싶지 않기 때문에, 매우 낮은 수준이지만 우리에게 매우 필요한 것을 수행하기 위해 "도우미"프로그램이나 라이브러리가 필요하다. 이러한 하위 수준이지만 필요한 것은 올바른 형식 확인, DTD 또는 스키마에 대한 문서 유효성 검사 (파서 유효성 검사 용), 문자 참조 확인, CDATA 섹션 이해 등을 포함합니다. XML 파서는 그러한 "도우미"프로그램 일 뿐이며 이러한 모든 작업을 수행 할 것입니다. XML 파서를 사용하면 이러한 복잡성으로부터 보호받을 수 있으며 파서에 의해 구현 된 API를 통해 높은 수준의 프로그래밍에만 집중할 수있어 프로그래밍 효율성을 얻을 수 있습니다.

SAX 또는 DOM 중 어느 것이 더 낫습니까?

SAX와 DOM 파서 모두 장단점이 있습니다. 어느 것이 더 나은지 응용 프로그램의 특성에 따라 달라집니다 (아래 몇 가지 질문을 참조하십시오).

어느 파서가 더 빠른 속도를 얻을 수 있습니까, DOM 또는 SAX 파서입니까?

SAX 파서는 더 빠른 속도를 얻을 수 있습니다.

트리 기반 API와 이벤트 기반 API의 차이점은 무엇입니까?

트리 기반 API는 트리 구조를 중심으로하기 때문에 문서 인터페이스, 노드 인터페이스, NodeList 인터페이스, 요소 인터페이스, Attr 인터페이스 등과 같은 트리의 컴포넌트 (DOM 문서)에 대한 인터페이스를 제공합니다. 그러나 이벤트 기반 API는 처리기에서 인터페이스를 제공합니다. 처리기 인터페이스에는 ContentHandler 인터페이스, DTDHandler 인터페이스, EntityResolver 인터페이스 및 ErrorHandler 인터페이스가 있습니다.

DOM 파서와 SAX 파서의 차이점은 무엇입니까?

DOM 파서와 SAX 파서는 다른 방식으로 작동합니다.

  • DOM 파서는 입력 문서에서 메모리에 트리 구조를 작성한 다음 클라이언트의 요청을 기다립니다. 그러나 SAX 파서는 내부 구조를 만들지 않습니다. 대신 입력 문서의 구성 요소 발생을 이벤트로 가져 와서 입력 문서를 읽을 때 읽은 내용을 클라이언트에 알려줍니다. ㅏ

  • DOM 파서는 클라이언트가 실제로 필요한 양에 관계없이 항상 전체 문서로 클라이언트 응용 프로그램을 제공합니다. 그러나 SAX 파서는 항상 주어진 시간에 문서 조각만으로 클라이언트 응용 프로그램을 제공합니다.

  • DOM 파서를 사용하면 클라이언트 응용 프로그램의 메서드 호출은 명시 적이어야하며 일종의 체인을 형성해야합니다. 그러나 SAX를 사용하면 특정 이벤트가 발생할 때 "콜백"이라고하는 방식으로 일부 메서드 (일반적으로 cient에 의해 재정의 됨)가 자동으로 호출됩니다. 이러한 메소드는 클라이언트가 명시 적으로 호출 할 필요는 없지만 명시 적으로 호출 할 수는 있습니다.

어떤 파서가 좋은지 어떻게 결정합니까?

이상적으로 좋은 파서는 빠르고 (시간 효율적) 공간 효율적이며 기능이 풍부하고 사용하기 쉬워야합니다. 그러나 실제로 주요 파서 중 어느 것도 이러한 기능을 동시에 가지고 있지 않습니다. 예를 들어, DOM 파서는 메모리에 DOM 트리를 작성하고 문서의 모든 부분에 반복적으로 액세스하고 DOM 트리를 수정할 수 있기 때문에 기능이 풍부하지만 문서가 크면 공간이 비효율적입니다 , 작업 방법을 배우는 데 약간의 시간이 걸립니다. 그러나 SAX 구문 분석기는 입력 문서가 큰 경우 (내부 구조를 작성하지 않기 때문에) 훨씬 공간 효율적입니다. 또한 API가 실제로 단순하기 때문에 DOM 파서보다 더 빠르게 실행하고 배우기 쉽습니다. 그러나 기능적인 관점에서 더 적은 기능을 제공하므로 사용자 자신의 데이터 구조 작성과 같이 사용자가 더 많은 정보를 처리해야합니다. 그런데 좋은 파서는 무엇입니까? 대답은 실제로 응용 프로그램의 특성에 달려 있다고 생각합니다.

DOM 파서를 사용하는 것보다 SAX 파서를 사용하는 것이 유리한 실제 응용 프로그램은 무엇입니까? DOM 파서와 SAX 파서의 일반적인 응용 프로그램은 무엇입니까?

다음과 같은 경우 SAX 파서를 사용하는 것이 DOM 파서를 사용하는 것보다 유리합니다.

  • 입력 문서가 사용 가능한 메모리에 비해 너무 큽니다 (실제로 SAX가 유일한 선택입니다)
  • 작은 연속 입력으로 문서를 처리 할 수 ​​있습니다. 유용한 작업을 수행하기 전에 전체 문서가 필요하지 않습니다
  • 파서를 사용하여 관심 정보를 추출하고 모든 계산은 사용자가 만든 데이터 구조를 완전히 기반으로합니다. 실제로 대부분의 응용 프로그램에서 우리는 일반적으로 DOM 트리만큼 복잡하지 않은 자체 데이터 구조를 만듭니다. 이런 의미에서 DOM 파서를 사용할 가능성은 SAX 파서를 사용하는 것보다 적습니다.

다음과 같은 경우 SAX 파서를 사용하는 것보다 DOM 파서를 사용하는 것이 유리합니다.

  • 응용 프로그램은 문서의 여러 부분에 동시에 액세스해야합니다.
  • 응용 프로그램은 아마도 문서 자체만큼이나 복잡한 내부 데이터 구조를 사용할 수 있습니다.
  • 응용 프로그램은 문서를 반복해서 수정해야합니다.
  • 애플리케이션은 많은 메소드 호출을 통해 문서를 상당한 시간 동안 저장해야합니다.

예 (DOM 파서 또는 SAX 파서를 사용 하시겠습니까?) :

강사가 학생의 모든 개인 정보와 수업 시간에 학생의 점수를 포함하는 XML 문서를 가지고 있다고 가정하고 이제는 응용 프로그램을 사용하여 학생들에게 최종 성적을 부여하고 있습니다. 그가 만들고자하는 것은 SSN과 성적 목록입니다. 또한 우리는 그의 응용 프로그램에서 강사가 학생 개인 정보와 포인트를 저장하기 위해 배열과 같은 데이터 구조를 사용하지 않는다고 가정합니다. 강사가 학급 평균 이상을 얻은 사람들에게 A를주고 다른 사람들에게 B를 주기로 결정한 경우, 그의 응용 프로그램에서 DOM 파서를 사용하는 것이 좋습니다. 그 이유는 전체 문서가 처리되기 전에 수업 평균이 얼마인지 알 수 없기 때문입니다. 그가 자신의 응용 프로그램에서해야 할 일은 먼저 모든 학생들의 점수를 매기고 평균을 계산 한 다음 문서를 다시 살펴보고 자신이 얻은 점수를 학급 평균과 비교하여 각 학생에게 최종 성적을 할당합니다. 그러나 강사가 90 점 이상을받은 학생에게 A가 할당되고 다른 학생에게 B가 할당되는 채점 정책을 채택하는 경우 SAX 파서를 사용하는 것이 좋습니다. 그 이유는 각 학생에게 최종 성적을 부여하기 위해 전체 문서가 처리 될 때까지 기다릴 필요가 없기 때문입니다. SAX 파서가이 학생의 성적을 읽으면 즉시 학생에게 성적을 할당 할 수 있습니다. 위의 분석에서 우리는 강사가 자신의 데이터 구조를 만들지 않았다고 가정했습니다. SSN을 저장하는 문자열 배열과 포인트를 저장하는 정수 배열과 같은 자체 데이터 구조를 만드는 경우 어떻게됩니까? 이 경우 SAX가 메모리와 시간을 절약하면서도 작업을 완료하기 전에 SAX가 더 나은 선택이라고 생각합니다. 이 예제에서 한 가지 더 고려해야 할 사항이 있습니다. 강사가 원하는 것은 목록을 인쇄하는 것이 아니라 업데이트 된 각 학생의 성적과 함께 원본 문서를 다시 저장하는 것입니까? 이 경우, 어떤 등급 정책을 채택하든 DOM 파서는 더 나은 선택이되어야합니다. 그는 자신의 데이터 구조를 만들 필요가 없습니다. 그가해야 할 일은 먼저 DOM 트리를 수정하고 (즉, 'grade'노드로 값을 설정 한 후) 수정 된 전체 트리를 저장하는 것입니다. 만약 그가 DOM 파서 대신 SAX 파서를 사용하기로 선택한다면,이 경우 그는 작업을 수행하기 전에 DOM 트리와 거의 같은 데이터 구조를 만들어야합니다. 아직 작업을 완료하십시오. 이 예제에서 한 가지 더 고려해야 할 사항이 있습니다. 강사가 원하는 것은 목록을 인쇄하는 것이 아니라 업데이트 된 각 학생의 성적과 함께 원본 문서를 다시 저장하는 것입니까? 이 경우, 어떤 등급 정책을 채택하든 DOM 파서는 더 나은 선택이되어야합니다. 그는 자신의 데이터 구조를 만들 필요가 없습니다. 그가해야 할 일은 먼저 DOM 트리를 수정하고 (즉, 'grade'노드로 값을 설정 한 후) 수정 된 전체 트리를 저장하는 것입니다. 만약 그가 DOM 파서 대신 SAX 파서를 사용하기로 선택한다면,이 경우 그는 작업을 수행하기 전에 DOM 트리와 거의 같은 데이터 구조를 만들어야합니다. 아직 작업을 완료하십시오. 이 예제에서 한 가지 더 고려해야 할 사항이 있습니다. 강사가 원하는 것은 목록을 인쇄하는 것이 아니라 업데이트 된 각 학생의 성적과 함께 원본 문서를 다시 저장하는 것입니까? 이 경우, 어떤 등급 정책을 채택하든 DOM 파서는 더 나은 선택이되어야합니다. 그는 자신의 데이터 구조를 만들 필요가 없습니다. 그가해야 할 일은 먼저 DOM 트리를 수정하고 (즉, 'grade'노드로 값을 설정 한 후) 수정 된 전체 트리를 저장하는 것입니다. 만약 그가 DOM 파서 대신 SAX 파서를 사용하기로 선택한다면,이 경우 그는 작업을 수행하기 전에 DOM 트리와 거의 같은 데이터 구조를 만들어야합니다. 하지만 각 학생의 성적이 업데이트 된 원본 문서를 다시 저장하려면? 이 경우, 어떤 등급 정책을 채택하든 DOM 파서는 더 나은 선택이되어야합니다. 그는 자신의 데이터 구조를 만들 필요가 없습니다. 그가해야 할 일은 먼저 DOM 트리를 수정하고 (즉, 'grade'노드로 값을 설정 한 후) 수정 된 전체 트리를 저장하는 것입니다. 만약 그가 DOM 파서 대신 SAX 파서를 사용하기로 선택한다면,이 경우 그는 작업을 수행하기 전에 DOM 트리와 거의 같은 데이터 구조를 만들어야합니다. 하지만 각 학생의 성적이 업데이트 된 원본 문서를 다시 저장하려면? 이 경우, 어떤 등급 정책을 채택하든 DOM 파서는 더 나은 선택이되어야합니다. 그는 자신의 데이터 구조를 만들 필요가 없습니다. 그가해야 할 일은 먼저 DOM 트리를 수정하고 (즉, 'grade'노드로 값을 설정 한 후) 수정 된 전체 트리를 저장하는 것입니다. 만약 그가 DOM 파서 대신 SAX 파서를 사용하기로 선택한다면,이 경우 그는 작업을 수행하기 전에 DOM 트리와 거의 같은 데이터 구조를 만들어야합니다. 노드)를 수정 한 다음 수정 된 전체 트리를 저장하십시오. 만약 그가 DOM 파서 대신 SAX 파서를 사용하기로 선택한다면,이 경우 그는 작업을 수행하기 전에 DOM 트리와 거의 같은 데이터 구조를 만들어야합니다. 노드)를 수정 한 다음 수정 된 전체 트리를 저장하십시오. 만약 그가 DOM 파서 대신 SAX 파서를 사용하기로 선택한다면,이 경우 그는 작업을 수행하기 전에 DOM 트리와 거의 같은 데이터 구조를 만들어야합니다.

문제점 설명 : 주어진 XML 문서의 요소 인 원에 대한 모든 정보를 추출하는 Java 프로그램을 작성하십시오. 각 원 요소에는 세 가지 하위 요소 (예 : x, y 및 반지름)와 색상 속성이 있다고 가정합니다. 샘플 문서는 다음과 같습니다.

<?xml version="1.0"?> 
<!DOCTYPE shapes [
<!ELEMENT shapes (circle)*>
<!ELEMENT circle (x,y,radius)>
<!ELEMENT x (#PCDATA)>
<!ELEMENT y (#PCDATA)>
<!ELEMENT radius (#PCDATA)>
<!ATTLIST circle color CDATA #IMPLIED>
]>

<shapes> 
          <circle color="BLUE"> 
                <x>20</x>
                <y>20</y>
                <radius>20</radius> 
          </circle>
          <circle color="RED" >
                <x>40</x>
                <y>40</y>
                <radius>20</radius> 
          </circle>
</shapes> 

DOMparser를 사용한 프로그램

import java.io.*;
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;


public class shapes_DOM {
   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers  
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles 

   public static void main(String[] args) {   

      try{
         // create a DOMParser
         DOMParser parser=new DOMParser();
         parser.parse(args[0]);

         // get the DOM Document object
         Document doc=parser.getDocument();

         // get all the circle nodes
         NodeList nodelist = doc.getElementsByTagName("circle");
         numberOfCircles =  nodelist.getLength();

         // retrieve all info about the circles
         for(int i=0; i<nodelist.getLength(); i++) {

            // get one circle node
            Node node = nodelist.item(i);

            // get the color attribute 
            NamedNodeMap attrs = node.getAttributes();
            if(attrs.getLength() > 0)
               color[i]=(String)attrs.getNamedItem("color").getNodeValue();

            // get the child nodes of a circle node 
            NodeList childnodelist = node.getChildNodes();

            // get the x and y value 
            for(int j=0; j<childnodelist.getLength(); j++) {
               Node childnode = childnodelist.item(j);
               Node textnode = childnode.getFirstChild();//the only text node
               String childnodename=childnode.getNodeName(); 
               if(childnodename.equals("x")) 
                  x[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("y")) 
                  y[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("radius")) 
                  r[i]= Integer.parseInt(textnode.getNodeValue().trim());
            }

         }

         // print the result
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }

      }  catch (Exception e) {e.printStackTrace(System.err);}

    }

}

SAXparser를 이용한 프로그램

import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;


public class shapes_SAX extends DefaultHandler {

   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles

   static int flagX=0;    //to remember what element has occurred
   static int flagY=0;    //to remember what element has occurred
   static int flagR=0;    //to remember what element has occurred

   // main method 
   public static void main(String[] args) {   
      try{
         shapes_SAX SAXHandler = new shapes_SAX (); // an instance of this class
         SAXParser parser=new SAXParser();          // create a SAXParser object 
         parser.setContentHandler(SAXHandler);      // register with the ContentHandler 
         parser.parse(args[0]);
      }  catch (Exception e) {e.printStackTrace(System.err);}  // catch exeptions
   }

   // override the startElement() method
   public void startElement(String uri, String localName, 
                       String rawName, Attributes attributes) {
         if(rawName.equals("circle"))                      // if a circle element is seen
            color[numberOfCircles]=attributes.getValue("color");  // get the color attribute 

         else if(rawName.equals("x"))      // if a x element is seen set the flag as 1 
            flagX=1;
         else if(rawName.equals("y"))      // if a y element is seen set the flag as 2
            flagY=1;
         else if(rawName.equals("radius")) // if a radius element is seen set the flag as 3 
            flagR=1;
   }

   // override the endElement() method
   public void endElement(String uri, String localName, String rawName) {
         // in this example we do not need to do anything else here
         if(rawName.equals("circle"))                       // if a circle element is ended 
            numberOfCircles +=  1;                          // increment the counter 
   }

   // override the characters() method
   public void characters(char characters[], int start, int length) {
         String characterData = 
             (new String(characters,start,length)).trim(); // get the text

         if(flagX==1) {        // indicate this text is for <x> element 
             x[numberOfCircles] = Integer.parseInt(characterData);
             flagX=0;
         }
         else if(flagY==1) {  // indicate this text is for <y> element 
             y[numberOfCircles] = Integer.parseInt(characterData);
             flagY=0;
         }
         else if(flagR==1) {  // indicate this text is for <radius> element 
             r[numberOfCircles] = Integer.parseInt(characterData);
             flagR=0;
         }
   }

   // override the endDocument() method
   public void endDocument() {
         // when the end of document is seen, just print the circle info 
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }
   }


}

6

실용적으로 : book.xml

<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
</bookstore>
  • DOM은 xml 문서를 메모리에 다음과 같은 트리 구조 로 표시합니다.
  • DOM은 W3C 표준입니다.
  • DOM 파서는 문서 객체 모델에서 작동합니다.
  • DOM은 더 많은 메모리를 차지하며 작은 XML 문서에 적합
  • DOM은 앞뒤로 탐색하기 쉽습니다.

여기에 이미지 설명을 입력하십시오


  • SAX가 같은 XML 문서 제시 기반 이벤트 와 같은을 start element:abc, end element:abc.
  • SAX는 W3C 표준이 아니며 개발자 그룹이 개발했습니다.
  • SAX는 메모리를 사용하지 않으므로 큰 XML 문서에 적합합니다.
  • 문서를 순차적으로 처리하므로 뒤로 탐색 할 수 없습니다.
  • 이벤트는 노드 / 요소에 발생하며 모든 하위 노드 (라틴어 노두, '노트')를 제공합니다.

이 XML 문서는 SAX 파서를 통해 전달 될 때 다음과 같은 일련의 이벤트를 생성합니다 .

start element: bookstore
start element: book with an attribute category equal to cooking
start element: title with an attribute lang equal to en
Text node, with data equal to Everyday Italian
....
end element: title
.....
end element: book
end element: bookstore

DOM 구문 분석의 시각적 표현에서 왜 attr: "lang"위의 것 element: <title>입니까? XML을 살펴보면 XML 과 와 attr평행 해야하는 것처럼 보입니다 . 그것은 단지 공간 절약 기술입니까, 아니면 부모-자식 관계가 있습니까? <element><book>category
1252748

그것은 단지 공간 절약 기술입니다
Premraj

3

DOM Document Object Model (문서 개체 모델)의 약자이며 각 요소가 트리 분기를 나타내는 XML 문서를 트리 형식으로 나타냅니다. DOM 구문 분석기는 XML 파일의 메모리 내 트리 표현을 작성한 후 구문 분석하므로 Java.lang.OutOfMemoryError : java heap space를 피하기 위해 DOM 구문 분석기의 힙 크기를 늘리는 데 더 많은 메모리가 필요합니다. XML 파일이 작 으면 DOM 파서를 사용하여 XML 파일을 파싱하는 것이 매우 빠르지 만 DOM 파서를 사용하여 큰 XML 파일을 읽으려고하면 시간이 오래 걸리거나 단순히 완전히로드하지 못할 수도 있습니다. XML Dom Tree를 만들려면 많은 메모리가 필요합니다. Java는 DOM 구문 분석을 지원하며 DOM 구문 분석기를 사용하여 Java에서 XML 파일을 구문 분석 할 수 있습니다. DOM 클래스는 w3c.dom 패키지에 있고 Java 용 DOM 구문 분석기는 JAXP (Java API for XML Parsing) 패키지에 있습니다.

Java의 SAX XML 파서

SAX는 XML 구문 분석을위한 간단한 API를 나타냅니다. 이것은 이벤트 기반 XML 구문 분석이며 XML 파일을 단계별로 구문 분석하여 큰 XML 파일에 매우 적합합니다. SAX XML 구문 분석기는 태그, 요소 또는 속성을 열 때 구문 분석이 작동하면 이벤트를 발생시킵니다. Java로 전체 XML 파일을로드 할 필요가없고 작은 부분으로 큰 XML 파일을 읽을 수 있으므로 Java에서 큰 xml 파일을 구문 분석하는 데 SAX XML 구문 분석기를 사용하는 것이 좋습니다. Java는 SAX 파서를 지원하며 SAX 파서를 사용하여 Java로 모든 XML 파일을 구문 분석 할 수 있습니다. 여기서는 SAX 파서를 사용하여 XML 파일을 읽는 예를 설명했습니다. Java에서 SAX 구문 분석기를 사용할 때의 한 가지 단점은 SAX 구문 분석기를 사용하여 Java에서 XML 파일을 읽으려면 DOM 구문 분석기와 비교하여 더 많은 코드가 필요하다는 것입니다.

DOM과 SAX XML 파서의 차이점

Java에서 DOM 파서와 SAX 파서의 차이점은 다음과 같습니다.

1) DOM 파서는 전체 XML 문서를 메모리에로드하고 SAX는 XML 파일의 작은 부분 만 메모리에로드합니다.

2) DOM 파서는 메모리의 전체 XML 문서에 액세스하기 때문에 SAX보다 빠릅니다.

3) Java의 SAX 파서는 메모리가 많이 필요하지 않기 때문에 DOM 파서보다 큰 XML 파일에 더 적합합니다.

4) DOM 파서는 Document Object Model에서 작동하지만 SAX는 이벤트 기반 XML 파서입니다.

더 읽기 : http://javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz2uz1bJQqZ


2

SAX와 DOM은 모두 XML 문서를 구문 분석하는 데 사용됩니다. 둘 다 장단점이 있으며 상황에 따라 프로그래밍에 사용할 수 있습니다

색소폰:

  1. 노드별로 구문 분석

  2. XML을 메모리에 저장하지 않습니다

  3. 노드를 삽입하거나 삭제할 수 없습니다

  4. 상단에서 하단으로 이송

DOM

  1. 처리하기 전에 전체 XML 문서를 메모리에 저장

  2. 더 많은 메모리를 차지

  3. 노드를 삽입하거나 삭제할 수 있습니다

  4. 어떤 방향 으로든 이동하십시오.

노드를 찾아야하거나 삽입하거나 삭제할 필요가없는 경우 SAX 자체를 사용할 수 있습니다. 그렇지 않으면 DOM에 더 많은 메모리가 제공됩니다.


1

1) DOM 파서는 전체 XML 문서를 메모리에로드하고 SAX는 XML 파일의 일부만 메모리에로드합니다.

2) DOM 파서는 메모리의 전체 XML 문서에 액세스하기 때문에 SAX보다 빠릅니다.

3) Java의 SAX 파서는 메모리가 많이 필요하지 않기 때문에 DOM 파서보다 큰 XML 파일에 더 적합합니다.

4) DOM 파서는 Document Object Model에서 작동하지만 SAX는 이벤트 기반 XML 파서입니다.

더 읽기 : http://javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz498y3vPFR

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.