Tôi luôn thấy XML hơi cồng kềnh khi xử lý. Tôi không nói về việc triển khai trình phân tích cú pháp XML: Tôi đang nói về việc sử dụng trình phân tích cú pháp dựa trên luồng hiện có, như trình phân tích cú pháp SAX, xử lý nút XML theo nút.
Đúng, thật dễ dàng để tìm hiểu các API khác nhau cho các trình phân tích cú pháp này, nhưng bất cứ khi nào tôi nhìn vào mã xử lý XML, tôi luôn thấy nó có phần khó hiểu. Vấn đề cốt yếu dường như là một tài liệu XML được phân tách hợp lý thành các nút riêng lẻ và các loại dữ liệu và thuộc tính thường được tách ra khỏi dữ liệu thực tế, đôi khi bởi nhiều cấp độ lồng nhau. Do đó, khi xử lý bất kỳ nút cụ thể nào, rất nhiều trạng thái bổ sung cần được duy trì để xác định chúng ta đang ở đâu và chúng ta cần làm gì tiếp theo.
Ví dụ: được cung cấp một đoạn trích từ một tài liệu XML điển hình:
<book>
<title>Blah blah</title>
<author>Blah blah</author>
<price>15 USD</price>
</book>
... Làm cách nào để xác định khi tôi gặp một nút văn bản có chứa tiêu đề sách? Giả sử chúng ta có một trình phân tích cú pháp XML đơn giản hoạt động như một trình vòng lặp, cung cấp cho chúng ta nút tiếp theo trong tài liệu XML mỗi khi chúng ta gọi XMLParser.getNextNode()
. Tôi chắc chắn thấy mình viết mã như sau:
boolean insideBookNode = false;
boolean insideTitleNode = false;
while (!XMLParser.finished())
{
....
XMLNode n = XMLParser.getNextNode();
if (n.type() == XMLTextNode)
{
if (insideBookNode && insideTitleNode)
{
// We have a book title, so do something with it
}
}
else
{
if (n.type() == XMLStartTag)
{
if (n.name().equals("book")) insideBookNode = true
else if (n.name().equals("title")) insideTitleNode = true;
}
else if (n.type() == XMLEndTag)
{
if (n.name().equals("book")) insideBookNode = false;
else if (n.name().equals("title")) insideTitleNode = false;
}
}
}
Về cơ bản, quá trình xử lý XML nhanh chóng biến thành một vòng lặp lớn do máy trạng thái điều khiển, với rất nhiều biến trạng thái được sử dụng để chỉ ra các nút cha mà chúng ta đã tìm thấy trước đó. Mặt khác, một đối tượng ngăn xếp cần được duy trì để theo dõi tất cả các thẻ lồng nhau. Điều này nhanh chóng trở nên dễ bị lỗi và khó bảo trì.
Một lần nữa, vấn đề dường như là dữ liệu chúng ta quan tâm không liên quan trực tiếp đến một nút riêng lẻ. Chắc chắn, nó có thể, nếu chúng ta viết XML như:
<book title="Blah blah" author="blah blah" price="15 USD" />
... nhưng đây hiếm khi là cách sử dụng XML trong thực tế. Hầu hết chúng ta có các nút văn bản là con của các nút cha và chúng ta cần theo dõi các nút cha để xác định xem nút văn bản đề cập đến điều gì.
Vậy ... tôi có làm gì sai không? Có cách nào tốt hơn? Tại thời điểm nào, việc sử dụng trình phân tích cú pháp dựa trên luồng XML trở nên quá cồng kềnh, do đó trình phân tích cú pháp DOM đầy đủ trở nên cần thiết? Tôi muốn nghe từ các lập trình viên khác loại thành ngữ nào họ sử dụng khi xử lý XML bằng các trình phân tích cú pháp dựa trên luồng. Phải phân tích cú pháp XML dựa trên luồng luôn biến thành một máy trạng thái khổng lồ?