Sự khác biệt giữa SAX và DOM là gì?


242

Tôi đọc một số bài viết về các trình phân tích cú pháp XML và tình cờ thấy SAXDOM .

SAX dựa trên sự kiện và DOM là mô hình cây - Tôi không hiểu sự khác biệt giữa các khái niệm này.

Từ những gì tôi đã hiểu, dựa trên sự kiện có nghĩa là một số loại sự kiện xảy ra với nút. Giống như khi một người bấm vào một nút cụ thể, nó sẽ cung cấp cho tất cả các nút phụ thay vì tải tất cả các nút cùng một lúc. Nhưng trong trường hợp phân tích cú pháp DOM, nó sẽ tải tất cả các nút và tạo mô hình cây.

Tôi hiểu có đúng không?

Vui lòng sửa cho tôi Nếu tôi sai hoặc giải thích cho tôi mô hình cây và dựa trên sự kiện một cách đơn giản hơn.


Nói một cách chính xác một DOM không phải là một trình phân tích cú pháp. Bất kỳ phần mềm dựa trên DOM nào cũng có thể hoặc không thể kết hợp phân tích cú pháp đánh dấu và hầu hết các phần mềm HTML DOM đều có. Nhưng DOM là một thứ hoàn toàn riêng biệt có thể không liên quan đến bất kỳ định dạng tuần tự hóa nào cả.
Bob77

Câu trả lời:


305

Vâng, bạn đang ở gần.

Trong SAX, các sự kiện được kích hoạt khi XML đang được phân tích cú pháp . Khi trình phân tích cú pháp đang phân tích cú pháp XML và bắt gặp một thẻ bắt đầu (ví dụ <something>), thì nó sẽ kích hoạt tagStartedsự kiện (tên thực tế của sự kiện có thể khác nhau). Tương tự như vậy khi kết thúc thẻ được đáp ứng trong khi phân tích cú pháp ( </something>), nó kích hoạt tagEnded. Sử dụng trình phân tích cú pháp SAX ngụ ý bạn cần xử lý các sự kiện này và hiểu ý nghĩa của dữ liệu được trả về với mỗi sự kiện.

Trong DOM, không có sự kiện nào được kích hoạt trong khi phân tích cú pháp. Toàn bộ XML được phân tích cú pháp và một cây DOM (của các nút trong XML) được tạo và trả về. Sau khi phân tích cú pháp, người dùng có thể điều hướng cây để truy cập các dữ liệu khác nhau được nhúng trước đó vào các nút khác nhau trong XML.

Nói chung, DOM dễ sử dụng hơn nhưng có chi phí phân tích toàn bộ XML trước khi bạn có thể bắt đầu sử dụng nó.


135
+1 - để làm rõ: sử dụng trình phân tích cú pháp DOM với các tệp nhỏ hơn phù hợp với RAM. Sử dụng trình phân tích cú pháp SAX cho các tệp lớn sẽ không.
Richard H

cảm ơn @spartkymat. Nhưng trong trường hợp SAX dựa trên sự kiện, trình phân tích SAX có thể biết nút con cụ thể là con của cha mẹ cụ thể không? Hoặc đơn giản là nó sẽ phân tích cú pháp? ví dụ. tôi có một <công ty> và con là <nhân viên>. Vì vậy, trong trường hợp này, những công ty và nhân viên đó sẽ chỉ được phân tích cú pháp hoặc nó sẽ cho thấy mối quan hệ mà công ty là cha mẹ của nhân viên?
dùng414967

4
Nó sẽ chỉ phân tích cú pháp. Bạn sẽ phải tự duy trì thông tin đó (thông qua một máy trạng thái hoặc cách khác). Tất cả lý do để sử dụng trình phân tích cú pháp DOM (nếu tài nguyên cho phép) :-).
Sparkymat

1
@Richard H Tôi cho rằng bất cứ ai sử dụng các tệp XML quá lớn mà họ không phù hợp với RAM đều làm điều gì đó rất sai.
antred

1
tải một excel có kích thước 40m, sử dụng bộ nhớ 200m khi sử dụng trình phân tích cú pháp SAX, nhưng sử dụng bộ nhớ 9g khi sử dụng trình phân tích cú pháp DOM.
zhiyuan_

98

Chỉ trong vài từ ...

SAX ( S imple A PI cho X ML): Là bộ xử lý dựa trên luồng. Bạn chỉ có một phần nhỏ trong bộ nhớ bất cứ lúc nào và bạn "đánh hơi" luồng XML bằng cách triển khai mã gọi lại cho các sự kiện như tagStarted()v.v. Nó hầu như không sử dụng bộ nhớ, nhưng bạn không thể thực hiện công cụ "DOM", như sử dụng xpath hoặc traverse cây.

DOM ( D ocument O bject M odel ): Bạn tải toàn bộ vào bộ nhớ - đó là một bộ nhớ lớn. Bạn có thể thổi bộ nhớ với các tài liệu cỡ vừa. Nhưng bạn có thể sử dụng xpath và đi qua cây, v.v.


66

Ở đây bằng những từ đơn giản hơn:

DOM

  • Trình phân tích mô hình cây (Dựa trên đối tượng) (Cây của các nút).

  • DOM tải tệp vào bộ nhớ và sau đó phân tích tệp.

  • Có các ràng buộc về bộ nhớ vì nó tải toàn bộ tệp XML trước khi phân tích cú pháp.

  • DOM được đọc và ghi (có thể chèn hoặc xóa các nút).

  • Nếu nội dung XML nhỏ, thì thích trình phân tích cú pháp DOM.

  • Có thể tìm kiếm lùi và tiến để tìm kiếm các thẻ và đánh giá thông tin bên trong các thẻ. Vì vậy, điều này cho phép dễ dàng điều hướng.

  • Chậm hơn trong thời gian chạy.

KÈN

  • Trình phân tích cú pháp dựa trên sự kiện (Trình tự các sự kiện).

  • SAX phân tích tệp khi nó đọc nó, tức là phân tích nút theo nút.

  • Không có ràng buộc về bộ nhớ vì nó không lưu trữ nội dung XML trong bộ nhớ.

  • SAX chỉ được đọc tức là không thể chèn hoặc xóa nút.

  • Sử dụng trình phân tích cú pháp SAX khi nội dung bộ nhớ lớn.

  • SAX đọc tệp XML từ trên xuống dưới và điều hướng lùi là không thể.

  • Nhanh hơn trong thời gian chạy.


hoàn hảo ... đã mong đợi một số câu trả lời trong các điểm. Làm tốt lắm :)
Kunal Gupta

37

Bạn hiểu đúng về mô hình dựa trên DOM. Tệp XML sẽ được tải toàn bộ và tất cả nội dung của nó sẽ được xây dựng dưới dạng biểu diễn trong bộ nhớ của cây mà tài liệu đại diện. Điều này có thể tiêu tốn thời gian và bộ nhớ, tùy thuộc vào mức độ lớn của tệp đầu vào. Lợi ích của phương pháp này là bạn có thể dễ dàng truy vấn bất kỳ phần nào của tài liệu và tự do thao tác tất cả các nút trong cây.

Cách tiếp cận DOM thường được sử dụng cho các cấu trúc XML nhỏ (trong đó nhỏ phụ thuộc vào mức độ mã lực và bộ nhớ mà nền tảng của bạn có) có thể cần được sửa đổi và truy vấn theo các cách khác nhau khi chúng được tải.

Mặt khác, SAX được thiết kế để xử lý đầu vào XML có kích thước gần như bất kỳ. Thay vì khung XML làm công việc khó khăn cho bạn trong việc tìm ra cấu trúc của tài liệu và chuẩn bị rất nhiều đối tượng cho tất cả các nút, thuộc tính, v.v., SAX hoàn toàn để lại cho bạn.

Những gì nó về cơ bản là đọc đầu vào từ đầu và gọi các phương thức gọi lại mà bạn cung cấp khi "sự kiện" nhất định xảy ra. Một sự kiện có thể đang đánh một thẻ mở, một thuộc tính trong thẻ, tìm văn bản bên trong một phần tử hoặc đi qua một thẻ kết thúc.

SAX ngoan cố đọc đầu vào và cho bạn biết những gì nó nhìn thấy trong thời trang này. Tùy thuộc vào bạn để duy trì tất cả các thông tin nhà nước bạn yêu cầu. Thông thường, điều này có nghĩa là bạn sẽ xây dựng một số loại máy trạng thái.

Mặc dù cách tiếp cận xử lý XML này tẻ nhạt hơn rất nhiều, nhưng nó cũng có thể rất mạnh mẽ. Hãy tưởng tượng bạn muốn trích xuất tiêu đề của các bài báo từ một nguồn cấp dữ liệu blog. Nếu bạn đọc XML này bằng DOM, nó sẽ tải tất cả nội dung bài viết, tất cả các hình ảnh, v.v. được chứa trong XML vào bộ nhớ, mặc dù bạn thậm chí không quan tâm đến nó.

Với SAX, bạn chỉ có thể kiểm tra xem tên thành phần là (ví dụ) "title" bất cứ khi nào phương thức sự kiện "startTag" của bạn được gọi. Nếu vậy, bạn biết rằng bạn cần thêm bất cứ điều gì sự kiện "ElementText" tiếp theo cung cấp cho bạn. Khi bạn nhận được cuộc gọi sự kiện "endTag", bạn kiểm tra lại xem đây có phải là phần tử đóng của "tiêu đề" không. Sau đó, bạn chỉ cần bỏ qua tất cả các yếu tố khác, cho đến khi đầu vào kết thúc hoặc một "startTag" khác có tên "title" xuất hiện. Và như thế...

Bạn có thể đọc qua megabyte và megabyte XML theo cách này, chỉ cần trích xuất lượng dữ liệu nhỏ bạn cần.

Dĩ nhiên, mặt tiêu cực của cách tiếp cận này là bạn cần phải tự mình giữ nhiều sách hơn, tùy thuộc vào dữ liệu bạn cần trích xuất và cấu trúc XML phức tạp như thế nào. Hơn nữa, bạn tự nhiên không thể sửa đổi cấu trúc của cây XML, vì bạn không bao giờ có nó trong tay.

Vì vậy, nói chung, SAX phù hợp để kết hợp với lượng dữ liệu tiềm năng lớn mà bạn nhận được với một "truy vấn" cụ thể, nhưng không cần sửa đổi, trong khi DOM nhằm mục đích giúp bạn linh hoạt hơn trong việc thay đổi cấu trúc và nội dung, với chi phí nhu cầu tài nguyên cao hơn.


16

Bạn đang so sánh táo và lê. SAX là một trình phân tích cú pháp phân tích cú pháp các cấu trúc DOM được tuần tự hóa. Có nhiều trình phân tích cú pháp khác nhau và "dựa trên sự kiện" đề cập đến phương pháp phân tích cú pháp.

Có thể một bản tóm tắt nhỏ theo thứ tự:

  • Các đối tượng tài liệu mô hình (DOM) là một mô hình dữ liệu trừu tượng mô tả một cây có trụ sở, tài liệu cấu trúc thứ bậc; một cây tài liệu bao gồm các nút , cụ thể là các nút phần tử, thuộc tính và văn bản (và một số nút khác). Các nút có cha mẹ, anh chị em và con cái và có thể được duyệt, v.v., tất cả những thứ bạn đã sử dụng để làm JavaScript (tình cờ không liên quan gì đến DOM).

  • Một cấu trúc DOM có thể được tuần tự hóa , tức là được ghi vào một tệp, sử dụng ngôn ngữ đánh dấu như HTML hoặc XML. Do đó, tệp HTML hoặc XML chứa phiên bản "viết ra" hoặc "làm phẳng" của cây tài liệu trừu tượng.

  • Đối với một máy tính để thao tác, hoặc hiển thị thậm chí, một cây DOM từ một tập tin, nó phải deserialize , hoặc phân tích cú pháp , các tập tin và xây dựng lại cây trừu tượng trong bộ nhớ. Đây là nơi phân tích cú pháp đi vào.

Bây giờ chúng ta đến với bản chất của trình phân tích cú pháp. Một cách để phân tích sẽ là đọc trong toàn bộ tài liệu và xây dựng đệ quy một cấu trúc cây trong bộ nhớ và cuối cùng hiển thị toàn bộ kết quả cho người dùng. (Tôi cho rằng bạn có thể gọi các trình phân tích cú pháp này là "Trình phân tích cú pháp DOM".) Điều đó sẽ rất tiện lợi cho người dùng (Tôi nghĩ đó là những gì trình phân tích cú pháp XML của PHP làm), nhưng nó gặp vấn đề về khả năng mở rộng và trở nên rất tốn kém đối với các tài liệu lớn.

Mặt khác, phân tích cú pháp dựa trên sự kiện , như được thực hiện bởi SAX, xem xét tệp một cách tuyến tính và chỉ đơn giản thực hiện các cuộc gọi lại cho người dùng bất cứ khi nào nó gặp một đoạn dữ liệu cấu trúc, như "phần tử này đã bắt đầu", "phần tử đó đã kết thúc" , "một số văn bản ở đây", v.v ... Điều này có lợi ích là nó có thể tồn tại mãi mãi mà không cần quan tâm đến kích thước tệp đầu vào, nhưng nó ở mức độ thấp hơn nhiều vì nó yêu cầu người dùng thực hiện tất cả công việc xử lý thực tế (bằng cách cung cấp gọi lại). Để trở về câu hỏi ban đầu của bạn, thuật ngữ "dựa trên sự kiện" dùng để chỉ những sự kiện phân tích cú pháp mà trình phân tích cú pháp đưa ra khi nó đi qua tệp XML.

Các bài viết trên Wikipedia có nhiều chi tiết về các giai đoạn của SAX phân tích cú pháp.


11

Tôi sẽ cung cấp câu trả lời theo định hướng Q & A chung cho câu hỏi này:

Trả lời câu hỏi

Tại sao chúng ta cần trình phân tích cú pháp XML?

Chúng tôi cần trình phân tích cú pháp XML vì chúng tôi không muốn làm mọi thứ trong ứng dụng của mình từ đầu và chúng tôi cần một số chương trình hoặc thư viện "trợ giúp" để làm một cái gì đó ở mức độ thấp nhưng rất cần thiết đối với chúng tôi. Những điều cấp thấp nhưng cần thiết này bao gồm kiểm tra tính chính xác, xác thực tài liệu dựa trên DTD hoặc lược đồ của nó (chỉ để xác thực trình phân tích cú pháp), giải quyết tham chiếu ký tự, hiểu các phần CDATA, v.v. Các trình phân tích cú pháp XML chỉ là các chương trình "trợ giúp" như vậy và chúng sẽ thực hiện tất cả các công việc này. Với trình phân tích cú pháp XML, chúng tôi được bảo vệ khỏi rất nhiều sự phức tạp này và chúng tôi có thể tập trung vào việc lập trình ở cấp độ cao thông qua API do các trình phân tích cú pháp triển khai và do đó đạt được hiệu quả lập trình.

Cái nào tốt hơn, SAX hay DOM?

Cả trình phân tích cú pháp SAX và DOM đều có những ưu điểm và nhược điểm. Cái nào tốt hơn nên phụ thuộc vào đặc điểm của ứng dụng của bạn (vui lòng tham khảo một số câu hỏi dưới đây).

Trình phân tích cú pháp nào có thể nhận được tốc độ tốt hơn, trình phân tích cú pháp DOM hoặc SAX?

Trình phân tích cú pháp SAX có thể có tốc độ tốt hơn.

Sự khác biệt giữa API dựa trên cây và API dựa trên sự kiện là gì?

API dựa trên cây được tập trung xung quanh cấu trúc cây và do đó cung cấp giao diện trên các thành phần của cây (là tài liệu DOM) như giao diện Tài liệu, giao diện Node, giao diện NodeList, giao diện Element, giao diện Attr, v.v. Tuy nhiên, ngược lại, API dựa trên sự kiện cung cấp giao diện trên trình xử lý. Có bốn giao diện xử lý, giao diện ContentHandler, giao diện DTDHandler, giao diện EntityResolver và giao diện ErrorHandler.

Sự khác biệt giữa Trình phân tích cú pháp DOM và Trình phân tích cú pháp SAX là gì?

Trình phân tích cú pháp DOM và trình phân tích cú pháp SAX hoạt động theo các cách khác nhau:

  • Trình phân tích cú pháp DOM tạo cấu trúc cây trong bộ nhớ từ tài liệu đầu vào và sau đó chờ yêu cầu từ máy khách. Nhưng một trình phân tích cú pháp SAX không tạo ra bất kỳ cấu trúc bên trong. Thay vào đó, nó lấy sự xuất hiện của các thành phần của tài liệu đầu vào làm sự kiện và cho khách hàng biết những gì nó đọc khi đọc qua tài liệu đầu vào. Một

  • Trình phân tích cú pháp DOM luôn phục vụ ứng dụng khách với toàn bộ tài liệu cho dù máy khách có thực sự cần bao nhiêu. Nhưng trình phân tích cú pháp SAX luôn phục vụ ứng dụng khách luôn chỉ với các phần của tài liệu tại bất kỳ thời điểm nào.

  • Với trình phân tích cú pháp DOM, các lệnh gọi phương thức trong ứng dụng khách phải rõ ràng và tạo thành một loại chuỗi. Nhưng với SAX, một số phương thức nhất định (thường được ghi đè bởi bệnh nhân) sẽ được gọi tự động (ngầm) theo cách gọi là "gọi lại" khi một số sự kiện nhất định xảy ra. Các phương thức này không phải được khách hàng gọi một cách rõ ràng, mặc dù chúng ta có thể gọi chúng một cách rõ ràng.

Làm thế nào để chúng ta quyết định về trình phân tích cú pháp nào là tốt?

Lý tưởng nhất là một trình phân tích cú pháp tốt phải nhanh (hiệu quả về thời gian), không gian hiệu quả, giàu chức năng và dễ sử dụng. Nhưng trong thực tế, không có trình phân tích cú pháp chính nào có tất cả các tính năng này cùng một lúc. Ví dụ: Trình phân tích cú pháp DOM có nhiều chức năng (vì nó tạo một cây DOM trong bộ nhớ và cho phép bạn truy cập bất kỳ phần nào của tài liệu và cho phép bạn sửa đổi cây DOM), nhưng nó không hiệu quả khi tài liệu rất lớn và phải mất một chút thời gian để học cách làm việc với nó. Tuy nhiên, Trình phân tích SAX hiệu quả hơn về không gian trong trường hợp tài liệu đầu vào lớn (vì nó không tạo cấu trúc bên trong). Hơn thế nữa, nó chạy nhanh hơn và dễ học hơn DOM Parser vì API của nó thực sự đơn giản. Nhưng từ quan điểm chức năng, nó cung cấp ít chức năng hơn, điều đó có nghĩa là bản thân người dùng phải chăm sóc nhiều hơn, chẳng hạn như tạo cấu trúc dữ liệu của riêng họ. Nhân tiện, một trình phân tích cú pháp tốt là gì? Tôi nghĩ rằng câu trả lời thực sự phụ thuộc vào đặc điểm của ứng dụng của bạn.

Một số ứng dụng trong thế giới thực khi sử dụng trình phân tích cú pháp SAX có lợi hơn so với sử dụng trình phân tích cú pháp DOM và ngược lại? Ứng dụng thông thường cho trình phân tích cú pháp DOM và trình phân tích cú pháp SAX là gì?

Trong các trường hợp sau, sử dụng trình phân tích cú pháp SAX có lợi hơn so với sử dụng trình phân tích cú pháp DOM.

  • Tài liệu đầu vào quá lớn so với bộ nhớ khả dụng (thực tế trong trường hợp này SAX là lựa chọn duy nhất của bạn)
  • Bạn có thể xử lý tài liệu theo từng phần nhỏ của đầu vào. Bạn không cần toàn bộ tài liệu trước khi bạn có thể làm công việc hữu ích
  • Bạn chỉ muốn sử dụng trình phân tích cú pháp để trích xuất thông tin quan tâm và tất cả tính toán của bạn sẽ hoàn toàn dựa trên cấu trúc dữ liệu do chính bạn tạo. Trên thực tế trong hầu hết các ứng dụng của chúng tôi, chúng tôi tạo các cấu trúc dữ liệu của riêng chúng thường không phức tạp như cây DOM. Từ ý nghĩa này, tôi nghĩ, cơ hội sử dụng trình phân tích cú pháp DOM ít hơn so với sử dụng trình phân tích cú pháp SAX.

Trong các trường hợp sau, sử dụng trình phân tích cú pháp DOM có lợi hơn so với sử dụng trình phân tích cú pháp SAX.

  • Ứng dụng của bạn cần truy cập nhiều phần riêng biệt của tài liệu cùng một lúc.
  • Ứng dụng của bạn có thể sử dụng cấu trúc dữ liệu nội bộ gần như phức tạp như chính tài liệu.
  • Ứng dụng của bạn phải sửa đổi tài liệu nhiều lần.
  • Ứng dụng của bạn phải lưu trữ tài liệu trong một khoảng thời gian đáng kể thông qua nhiều cuộc gọi phương thức.

Ví dụ (Sử dụng trình phân tích cú pháp DOM hoặc trình phân tích cú pháp SAX?):

Giả sử rằng một người hướng dẫn có một tài liệu XML chứa tất cả thông tin cá nhân của sinh viên cũng như những điểm mà sinh viên của anh ta đưa ra trong lớp và hiện anh ta đang chỉ định điểm cuối cho các sinh viên sử dụng một ứng dụng. Những gì anh ấy muốn sản xuất, là một danh sách với SSN và điểm số. Ngoài ra, chúng tôi giả định rằng trong ứng dụng của mình, người hướng dẫn không sử dụng cấu trúc dữ liệu như mảng để lưu trữ thông tin cá nhân của sinh viên và các điểm. Nếu người hướng dẫn quyết định đưa A cho những người kiếm được điểm trung bình hoặc cao hơn và đưa B cho những người khác, thì tốt hơn hết là bạn nên sử dụng trình phân tích cú pháp DOM trong ứng dụng của mình. Lý do là anh ta không có cách nào để biết mức trung bình của lớp là bao nhiêu trước khi toàn bộ tài liệu được xử lý. Những gì anh ấy có thể cần phải làm trong ứng dụng của mình, trước tiên là xem qua tất cả các sinh viên điểm và tính điểm trung bình, sau đó xem lại tài liệu và chỉ định điểm cuối cùng cho mỗi học sinh bằng cách so sánh điểm anh ta kiếm được với điểm trung bình của lớp. Tuy nhiên, nếu người hướng dẫn áp dụng chính sách chấm điểm như vậy mà các sinh viên đạt 90 điểm trở lên, được chỉ định A và những người khác được chỉ định B, thì có lẽ anh ta nên sử dụng trình phân tích cú pháp SAX. Lý do là, để chỉ định cho mỗi học sinh một lớp cuối cùng, anh ta không cần phải đợi toàn bộ tài liệu được xử lý. Anh ta có thể ngay lập tức chỉ định một lớp cho một học sinh sau khi trình phân tích cú pháp SAX đọc lớp của học sinh này. Trong phân tích trên, chúng tôi giả định rằng người hướng dẫn không tạo ra cấu trúc dữ liệu của riêng mình. Điều gì sẽ xảy ra nếu anh ta tạo cấu trúc dữ liệu của riêng mình, chẳng hạn như một chuỗi các chuỗi để lưu trữ SSN và một mảng các số nguyên để lấy lại các điểm? Trong trường hợp này, Tôi nghĩ SAX là một lựa chọn tốt hơn, trước khi điều này có thể tiết kiệm cả bộ nhớ và thời gian, nhưng vẫn hoàn thành công việc. Vâng, một xem xét thêm về ví dụ này. Điều gì sẽ xảy ra nếu những gì người hướng dẫn muốn làm không phải là in một danh sách, mà là để lưu lại tài liệu gốc với điểm của mỗi sinh viên được cập nhật? Trong trường hợp này, trình phân tích cú pháp DOM sẽ là lựa chọn tốt hơn cho dù anh ta đang áp dụng chính sách phân loại nào. Anh ta không cần phải tạo bất kỳ cấu trúc dữ liệu nào của riêng mình. Những gì anh ta cần làm là trước tiên sửa đổi cây DOM (nghĩa là đặt giá trị thành nút 'lớp') và sau đó lưu toàn bộ cây đã sửa đổi. Nếu anh ta chọn sử dụng trình phân tích cú pháp SAX thay vì trình phân tích cú pháp DOM, thì trong trường hợp này anh ta phải tạo một cấu trúc dữ liệu gần như phức tạp như một cây DOM trước khi anh ta có thể hoàn thành công việc. chưa hoàn thành công việc Vâng, một xem xét thêm về ví dụ này. Điều gì sẽ xảy ra nếu những gì người hướng dẫn muốn làm không phải là in một danh sách, mà là để lưu lại tài liệu gốc với điểm của mỗi sinh viên được cập nhật? Trong trường hợp này, trình phân tích cú pháp DOM sẽ là lựa chọn tốt hơn cho dù anh ta đang áp dụng chính sách phân loại nào. Anh ta không cần phải tạo bất kỳ cấu trúc dữ liệu nào của riêng mình. Những gì anh ta cần làm là trước tiên sửa đổi cây DOM (nghĩa là đặt giá trị thành nút 'lớp') và sau đó lưu toàn bộ cây đã sửa đổi. Nếu anh ta chọn sử dụng trình phân tích cú pháp SAX thay vì trình phân tích cú pháp DOM, thì trong trường hợp này anh ta phải tạo một cấu trúc dữ liệu gần như phức tạp như một cây DOM trước khi anh ta có thể hoàn thành công việc. chưa hoàn thành công việc Vâng, một xem xét thêm về ví dụ này. Điều gì sẽ xảy ra nếu những gì người hướng dẫn muốn làm không phải là in một danh sách, mà là để lưu lại tài liệu gốc với điểm của mỗi sinh viên được cập nhật? Trong trường hợp này, trình phân tích cú pháp DOM sẽ là lựa chọn tốt hơn cho dù anh ta đang áp dụng chính sách phân loại nào. Anh ta không cần phải tạo bất kỳ cấu trúc dữ liệu nào của riêng mình. Những gì anh ta cần làm là trước tiên sửa đổi cây DOM (nghĩa là đặt giá trị thành nút 'lớp') và sau đó lưu toàn bộ cây đã sửa đổi. Nếu anh ta chọn sử dụng trình phân tích cú pháp SAX thay vì trình phân tích cú pháp DOM, thì trong trường hợp này anh ta phải tạo một cấu trúc dữ liệu gần như phức tạp như một cây DOM trước khi anh ta có thể hoàn thành công việc. Nhưng để lưu tài liệu gốc trở lại với điểm của từng học sinh được cập nhật? Trong trường hợp này, trình phân tích cú pháp DOM sẽ là lựa chọn tốt hơn cho dù anh ta đang áp dụng chính sách phân loại nào. Anh ta không cần phải tạo bất kỳ cấu trúc dữ liệu nào của riêng mình. Những gì anh ta cần làm là trước tiên sửa đổi cây DOM (nghĩa là đặt giá trị thành nút 'lớp') và sau đó lưu toàn bộ cây đã sửa đổi. Nếu anh ta chọn sử dụng trình phân tích cú pháp SAX thay vì trình phân tích cú pháp DOM, thì trong trường hợp này anh ta phải tạo một cấu trúc dữ liệu gần như phức tạp như một cây DOM trước khi anh ta có thể hoàn thành công việc. Nhưng để lưu tài liệu gốc trở lại với điểm của từng học sinh được cập nhật? Trong trường hợp này, trình phân tích cú pháp DOM sẽ là lựa chọn tốt hơn cho dù anh ta đang áp dụng chính sách phân loại nào. Anh ta không cần phải tạo bất kỳ cấu trúc dữ liệu nào của riêng mình. Những gì anh ta cần làm là trước tiên sửa đổi cây DOM (nghĩa là đặt giá trị thành nút 'lớp') và sau đó lưu toàn bộ cây đã sửa đổi. Nếu anh ta chọn sử dụng trình phân tích cú pháp SAX thay vì trình phân tích cú pháp DOM, thì trong trường hợp này anh ta phải tạo một cấu trúc dữ liệu gần như phức tạp như một cây DOM trước khi anh ta có thể hoàn thành công việc. nút) và sau đó lưu toàn bộ cây sửa đổi. Nếu anh ta chọn sử dụng trình phân tích cú pháp SAX thay vì trình phân tích cú pháp DOM, thì trong trường hợp này anh ta phải tạo một cấu trúc dữ liệu gần như phức tạp như một cây DOM trước khi anh ta có thể hoàn thành công việc. nút) và sau đó lưu toàn bộ cây sửa đổi. Nếu anh ta chọn sử dụng trình phân tích cú pháp SAX thay vì trình phân tích cú pháp DOM, thì trong trường hợp này anh ta phải tạo một cấu trúc dữ liệu gần như phức tạp như một cây DOM trước khi anh ta có thể hoàn thành công việc.

Một ví dụ

Báo cáo sự cố : Viết chương trình Java để trích xuất tất cả thông tin về các vòng tròn là các thành phần trong tài liệu XML đã cho. Chúng tôi giả định rằng mỗi phần tử vòng tròn có ba phần tử con (nghĩa là x, y và bán kính) cũng như một thuộc tính màu. Một tài liệu mẫu được đưa ra dưới đâ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> 

Chương trình với 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);}

    }

}

Chương trình với 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

Trong thực tế: 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 trình bày tài liệu xml dưới dạng cấu trúc cây sau đây trong bộ nhớ.
  • DOM là tiêu chuẩn W3C.
  • Trình phân tích cú pháp DOM hoạt động trên Mô hình đối tượng tài liệu.
  • DOM chiếm nhiều bộ nhớ hơn, được ưu tiên cho các tài liệu XML nhỏ
  • DOM dễ dàng điều hướng tiến hoặc lùi.

nhập mô tả hình ảnh ở đây


  • SAX trình bày tài liệu xml dưới dạng sự kiện như start element:abc, end element:abc.
  • SAX không phải là tiêu chuẩn W3C, nó được phát triển bởi nhóm các nhà phát triển.
  • SAX không sử dụng bộ nhớ, được ưu tiên cho các tài liệu XML lớn.
  • Điều hướng lùi là không thể vì nó xử lý tuần tự các tài liệu.
  • Sự kiện xảy ra với một nút / phần tử và nó cung cấp cho tất cả các nút phụ (nút Latin, 'nút').

Tài liệu XML này, khi được chuyển qua trình phân tích cú pháp SAX, sẽ tạo ra một chuỗi các sự kiện như sau :

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

Tại sao attr: "lang"ở trên element: <title>trong biểu diễn trực quan của phân tích cú pháp DOM? Nhìn vào XML, có vẻ như attrcần phải song song với nó <element>như với <book>category. Có phải đó chỉ là một kỹ thuật tiết kiệm không gian hoặc có một mối quan hệ cha-con dự định?
1252748

nó chỉ là một kỹ thuật tiết kiệm không gian
Premraj

3

DOM Stands cho Mô hình Đối tượng Tài liệu và nó đại diện cho Tài liệu XML thành định dạng cây mà mỗi phần tử đại diện cho các nhánh cây. DOM Parser tạo một biểu diễn cây XML trong bộ nhớ của tệp XML và sau đó phân tích cú pháp nó, do đó, nó đòi hỏi nhiều bộ nhớ hơn và nên tăng kích thước heap cho trình phân tích cú pháp DOM để tránh không gian heap Java.lang.OutOfMemoryError: java. Phân tích tệp XML bằng trình phân tích cú pháp DOM khá nhanh nếu tệp XML nhỏ nhưng nếu bạn cố đọc một tệp XML lớn bằng trình phân tích cú pháp DOM thì có nhiều khả năng sẽ mất nhiều thời gian hoặc thậm chí có thể không tải được hoàn toàn đơn giản vì nó đòi hỏi rất nhiều bộ nhớ để tạo XML Dom Tree. Java cung cấp hỗ trợ Phân tích cú pháp DOM và bạn có thể phân tích các tệp XML trong Java bằng cách sử dụng trình phân tích cú pháp DOM. Các lớp DOM nằm trong gói w3c.dom trong khi DOM Parser cho Java nằm trong gói JAXP (Java API cho phân tích cú pháp XML).

Trình phân tích cú pháp XML SAX trong Java

SAX viết tắt cho API đơn giản để phân tích cú pháp XML. Đây là một phân tích cú pháp XML dựa trên sự kiện và nó phân tích từng bước tệp XML rất phù hợp với các tệp XML lớn. SAX XML Parser kích hoạt sự kiện khi nó gặp thẻ mở, phần tử hoặc thuộc tính và phân tích cú pháp hoạt động tương ứng. Bạn nên sử dụng trình phân tích cú pháp XML SAX để phân tích các tệp xml lớn trong Java vì không yêu cầu tải toàn bộ tệp XML trong Java và nó có thể đọc một tệp XML lớn thành các phần nhỏ. Java cung cấp hỗ trợ cho trình phân tích cú pháp SAX và bạn có thể phân tích bất kỳ tệp xml nào trong Java bằng SAX Parser, tôi đã trình bày ví dụ về việc đọc tệp xml bằng SAX Parser tại đây. Một nhược điểm của việc sử dụng SAX Parser trong java là việc đọc tệp XML trong Java bằng SAX Parser yêu cầu nhiều mã hơn so với DOM Parser.

Sự khác biệt giữa DOM và SAX XML Parser

Dưới đây là một số khác biệt cấp cao giữa trình phân tích cú pháp DOM và Trình phân tích SAX trong Java:

1) Trình phân tích cú pháp DOM tải toàn bộ tài liệu xml trong bộ nhớ trong khi SAX chỉ tải một phần nhỏ tệp XML trong bộ nhớ.

2) Trình phân tích cú pháp DOM nhanh hơn SAX vì nó truy cập toàn bộ tài liệu XML trong bộ nhớ.

3) Trình phân tích cú pháp SAX trong Java phù hợp hơn với tệp XML lớn hơn Trình phân tích cú pháp DOM vì nó không đòi hỏi nhiều bộ nhớ.

4) Trình phân tích cú pháp DOM hoạt động trên Mô hình đối tượng tài liệu trong khi SAX là trình phân tích cú pháp xml dựa trên sự kiện.

Đọc thêm: http://javarevisited.blogspot.com/2011/12/difference-b between-in-and-sax-persers.html # ixzz2uz1bJQqZ


2

Cả SAX và DOM đều được sử dụng để phân tích tài liệu XML. Cả hai đều có ưu điểm và nhược điểm và có thể được sử dụng trong lập trình của chúng tôi tùy thuộc vào tình huống

KÈN:

  1. Phân tích nút theo nút

  2. Không lưu trữ XML trong bộ nhớ

  3. Chúng tôi không thể chèn hoặc xóa một nút

  4. Từ trên xuống dưới

DOM

  1. Lưu trữ toàn bộ tài liệu XML vào bộ nhớ trước khi xử lý

  2. Chiếm nhiều bộ nhớ

  3. Chúng tôi có thể chèn hoặc xóa các nút

  4. Đi qua bất kỳ hướng nào.

Nếu chúng ta cần tìm một nút và không cần chèn hoặc xóa, chúng ta có thể đi với chính SAX nếu không DOM miễn là chúng ta có nhiều bộ nhớ hơn.


1

1) Trình phân tích cú pháp DOM tải toàn bộ tài liệu XML trong bộ nhớ trong khi SAX chỉ tải một phần nhỏ của tệp XML trong bộ nhớ.

2) Trình phân tích cú pháp DOM nhanh hơn SAX vì nó truy cập toàn bộ tài liệu XML trong bộ nhớ.

3) Trình phân tích cú pháp SAX trong Java phù hợp hơn với tệp XML lớn hơn Trình phân tích cú pháp DOM vì nó không đòi hỏi nhiều bộ nhớ.

4) Trình phân tích cú pháp DOM hoạt động trên Mô hình đối tượng tài liệu trong khi SAX là trình phân tích cú pháp XML dựa trên sự kiện.

Đọc thêm: http://javarevisited.blogspot.com/2011/12/difference-b between-in-and-sax-persers.html # ixzz498y3vPFR

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.