XPath và SimpleXML cung cấp sự cân bằng hợp lý giữa khả năng đọc và sự
dài dòng trong các API phân tích cú pháp-XML
Tóm tắt: Google Calendar (Lịch của Google) và các ứng dụng lịch trực tuyến khác
cung cấp các hệ thống tập trung đơn giản ở nơi các cộng đồng trực tuyến có thể
duy trì các lịch sự kiện và các thành viên cộng đồng có thể nhận được thông
tin về các sự kiện sắp tới. Tuy nhiên, nhiều tổ chức thích hiển thị các lịch
sự kiện trên các cổng thông tin, các diễn đàn, hoặc các blog cộng đồng của họ.
Họ thường xuyên sao chép thông tin lịch sự kiện từ các ứng dụng tạo lịch trực
tuyến lên trang Web của họ, nên đã làm giảm hiệu quả của việc quản lý tập
trung trực tuyến các sự kiện. Google Calendar cung cấp một giao diện lập trình
ứng dụng (API) tích hợp nhằm cung cấp một giải pháp tốt cho vấn đề này. Hãy
tìm hiểu cách sử dụng XPath để trích xuất và hiển thị dữ liệu Google Calendar
trên trang Web PHP của bạn.
Trong lúc hành nghề tự do như một nhà phát triển Web một vài năm trước đây,
tôi đã phát triển một cổng thông tin Web có trang bị-PHP cho một cộng đồng
những người sở hữu và những người hâm mộ một mẫu ô tô cụ thể (thường được
gọi là câu lạc bộ xe hơi đang rất phổ biến ở nơi tôi sống). Một vài năm
trước khi liên hệ với tôi, một số các nhà lãnh đạo câu lạc bộ xe hơi đã
học được các kỹ năng Web cơ bản và đã tạo ra một trang Web riêng của họ.
Khi đã phát triển, trang Web này đã tích lũy được một số lượng lớn các
trang, một số trang trở nên nhàm chán, ở đó đăng lên thông tin lịch sự
kiện riêng biệt. Do mục đích chính của trang là thông báo cho công chúng
và các thành viên cộng đồng về các hoạt động, nên người ta đã đăng bừa bãi
thông tin lịch sự kiện lên các trang này.
Theo thời gian, những ảnh chụp màn hình tạp nham này về lịch sự kiện của
cộng đồng đã phát triển không đồng bộ. Một số trang vẫn có các thanh bên
thông báo các sự kiện đã lỗi thời. Ngay cả với việc quản lý đúng cách và
thiết kế Web hiệu quả, việc duy trì các bản sao dữ liệu lịch sự kiện riêng
biệt trên các trang riêng biệt là một quá trình tiêu tốn nhiều thời gian
và dễ bị lỗi. Thay vì trang Web của câu lạc bộ xe làm việc cho họ, họ lại
thấy mình làm việc chăm chỉ cho trang Web của mình. Họ liên lạc với tôi
với hy vọng rằng tôi có thể chỉ họ một cách tốt hơn.
Họ đã cần một trang Web có các diễn đàn ở đó các thành viên câu lạc bộ có
thể thảo luận về những chiếc xe yêu thích của mình và một trang tin tức
tập trung có các bài viết và các thông báo về sự kiện mới nhất. Trên trang
tin tức này, họ có thể thông báo cho thành viên đang tăng dần của mình về
các sự kiện, ví dụ như các cuộc gặp mặt, các chuyến đi caravan tới các
vùng đất và xung quanh các vùng nông thôn, và các cuộc họp thành viên
chung ở đó họ đã thảo luận về lệ phí hội viên và xem xét về dự thảo ngân
sách. Quan trọng hơn, họ không muốn phải duy trì nhiều hoặc càng nhiều bản
sao lịch sự kiện ở bất cứ đâu. Họ muốn đưa lịch sự kiện về một chỗ và có
thể truy cập thông tin đó từ bất cứ nơi nào khác trên trang Web.
Google Calendar
và API dữ liệu của Google
Các ứng dụng tạo lịch trực tuyến như Google Calendar cung cấp một giải
pháp. Nhờ tập trung hiển thị và quản lý các sự kiện, những người dùng
Google Calendar có thể chia sẻ và duy trì dữ liệu sự kiện tại một trang
Web, loại bỏ một trong nhiều nguồn sai sót khỏi quá trình tổ chức sự kiện.
Các thành viên cộng đồng có thể truy cập lịch trực tuyến để bám sát các sự
kiện sắp tới và các hoạt động mà không bị nhầm lẫn bởi thông tin sự kiện
quá hạn trên các trang Web riêng biệt. Có vẻ như các ứng dụng lịch trực
tuyến là giải pháp lý tưởng.
Trong khi phát triển trang Web của câu lạc bộ bằng hệ thống quản lý nội
dung Drupal (xem phần Tài nguyên), tôi đã đề nghị
các nhà lãnh đạo của câu lạc bộ sử dụng Google Calendar để duy trì lịch sự
kiện. Lúc đầu, họ đã hiểu được ý tưởng này, và họ đã báo cáo năng suất rất
cao vì đã dễ dàng sử dụng đầu vào quản trị của Drupal để cập nhật các
thanh bên sự kiện mà tôi đã tạo ra cho họ. Nhưng theo thời gian, sự thành
công của câu lạc bộ có nghĩa là có nhiều sự kiện hơn để thông báo, và việc
chỉnh sửa các thanh bên sự kiện đã chuyển từ vui vẻ và dễ dàng thành một
công việc vụn vặt khó chịu.
API dữ liệu của Google và việc truy cập của nó tới dữ liệu sự kiện Google
Calendar đã đưa ra một cách thực hiện để thoát ra khỏi tình trạng khó xử
này. API dữ liệu của Google cung cấp một công cụ của Giao thức xuất bản
Atom (APP), một API dịch vụ Web để đọc và cập nhật các kiểu tài liệu và
thông tin khác nhau. Ngoài ra còn có các API tích hợp của bên thứ ba cho
ngôn ngữ lập trình Microsoft® .NET, Java™,
Python và PHP chứa đựng nhiều chức năng của API dữ liệu Google trong một
tập các lớp trình bao hướng đối tượng.
Sau một số nghiên cứu, tôi đã có thể mở rộng trang Web Drupal của câu lạc
bộ xe hơi với một thanh bên sự kiện luôn cập nhật dữ liệu lịch sự kiện mới
nhất được lấy từ tài khoản Google Calendar.
Nguồn cung cấp
tin của Google Calendar
API dữ liệu Google cung cấp một số các nguồn cung cấp tin Atom có chứa các
tài liệu và thông tin với nhiều dịch vụ Web do Google cung cấp. Google
Calendar cũng không là ngoại lệ, cung cấp một số nguồn cung cấp tin đang
chứa đựng phần lớn dữ liệu của Google Calendar. Có các nguồn cung cấp tin
công khai và có xác thực HTTP. Để lấy ra và tương tác với nguồn cung cấp
tin có xác thực, máy khách HTTP cần phải cung cấp thông tin xác thực cùng
với yêu cầu
GET
của HTTP. Các nguồn cung cấp
tin có xác thực cũng có khả năng cập nhật tài khoản Google Calendar bằng
yêu cầu POST
của HTTP. Các máy khách HTTP đang
sử dụng các nguồn cung cấp tin có xác thực có thể thêm và loại bỏ các sự
kiện, đăng ký và huỷ đăng ký khỏi các lịch, và tạo và xóa các lịch khỏi
tài khoản Google.
Google Calendar API cung cấp các nguồn cung cấp tin để truy cập vào tất cả
các lịch cá nhân mà người dùng đã truy cập vào từ Giao diện người dùng đồ
họa (GUI) của Google Calendar. Việc này bao gồm các lịch thuộc sở hữu của
người dùng, các lịch thuộc sở hữu của người khác nhưng người dùng đã đăng
ký, và các lịch mà người dùng đã nhập khẩu trong trạng thái chỉ-đọc. Các
lịch này, mà mỗi cái đều là nguồn cấp tin riêng của mình, đã xác thực
các nguồn cung cấp tin sự kiện công khai và riêng tư, ở đó các
sự kiện cá nhân trong lịch được liệt kê. Bài viết này tập trung vào các
nguồn cung cấp tin sự kiện công khai.
Tạo công khai
nguồn cung cấp tin Google Calendar của bạn
Nguồn cung cấp tin sự kiện công khai của một lịch của Google Calendar,
trong đó một tài khoản có thể có nhiều, nhận được bằng cách đăng ký vào
ứng dụng Google Calendar, cách chọn lịch mà bạn đang quan tâm xử lý, và
cách nhấn vào mũi tên đi xuống nhỏ cạnh tên của lịch. Sau khi bạn nhấn vào
mũi tên này, một trình đơn hiển thị bên cạnh tên của nguồn cung cấp tin.
Chọn Calendar Settings (Các thiết lập Lịch), được khoanh tròn trong
Hình 1.
Hình 1. Trình đơn thả xuống Google Calendar cho một lịch được chọn
Sau đó, ứng dụng Google Calendar chuyển đến một trang ở đó bạn có thể chọn
các thiết lập lịch khác nhau, ví dụ như múi giờ cho các sự kiện và tên của
lịch. Một tùy chọn quan trọng cho các nguồn cung cấp tin công khai là liệu
lịch tự nó có là lịch công khai hay lịch chia sẻ không. Để làm cho
lịch của bạn được chia sẻ và có thể lấy ra thông qua nguồn cung cấp tin sự
kiện công khai, hãy nhấn chuột vào tùy chọn Change sharing settings
(Thay đổi các thiết lập chia sẻ), như trong Hình 2.
Hình 2. Thay đổi khả năng nhìn thấy của một lịch theo được chia sẻ hoặc công khai
Trang sẽ chuyển tới thẻ (tab) Share this calendar (Chia sẻ lịch
này), ở đây bạn có thể chọn Share all information on this calendar with
everyone (Chia sẻ tất cả thông tin trên lịch này với mọi người).
Một loạt các câu hỏi hiện lên sẽ hiển thị, hỏi liệu bạn có thực sự muốn
tạo công khai lịch của bạn không. Trả lời Yes (Có), và đừng quên
lưu các thiết lập của mình bằng cách nhấn chuột vào Save (Lưu) ở
phía dưới cùng của thẻ này. Nhấn vào Back to Calendar (Quay lại
Lịch) để tiếp tục bổ sung thêm các sự kiện vào lịch của bạn.
Xem xét một nguồn
cung cấp tin của Google Calendar
Với một ví dụ về một nguồn cung cấp tin của Google Calendar, hãy tham khảo
tệp full.xml trong ví dụ mã được cung cấp trong phần Tải về. Tôi cũng cung cấp một liên kết đến một nguồn cung cấp tin
giả được sử dụng trong các ví dụ mã trong bài viết này (xem phần Tài nguyên).
Các nguồn cung cấp tin sự kiện chứa các phần tử khác nhau để mô tả một sự
kiện, ví dụ như tên sự kiện, một đoạn mô tả, và ở đâu và khi nào sẽ diễn
ra sự kiện đó. Google Calendar cũng quản lý một danh sách những người được
mời đến sự kiện thông qua một danh sách các e-mail để gửi các thông tin
chi tiết sự kiện bất cứ khi nào email được cập nhật. Nếu các địa chỉ
e-mail này đại diện cho những người dùng Google Calendar, thì họ có thể
đáp ứng lời mời thông qua ứng dụng, và sự kiện này cũng duy trì trạng thái
tham dự của họ. Việc tích hợp với các thông tin chi tiết tham dự nằm ngoài
phạm vi của bài viết này, là chỉ tập trung vào thông tin sự kiện cơ bản,
ví dụ như tên sự kiện và khi nào và ở đâu các sự kiện sẽ diễn ra. Liệt kê
1 là một mục sự kiện từ nguồn cung cấp tin mẫu.
Liệt kê 1. Nguồn cung cấp tin sự kiện mẫu của Google Calendar: ID và các dấu thời gian
<entry> <id> http://www.google.com/calendar/feeds/foss.sanjuan%40gmail.com/public/full/ s19o15ve3nn209gv5qf6c43ao4 </id> <published>2007-08-12T15:45:40.000Z</published> <updated>2007-08-12T15:53:37.000Z</updated> ... ... |
Phần tử
id
(mã định danh) cung cấp một địa chỉ
URI (Uniform Resource Identifier - Trình định danh tài nguyên thống nhất)
duy nhất để nhận biết sự kiện này bên trong hệ thống Google Calendar. Phần
tử này không chỉ chứa một số duy nhất mà còn nhận biết nguồn cung cấp tin
từ đó lấy ra nó. Các phần tử published
(đã công
bố) và updated
(đã cập nhật) sử dụng định dạng
dấu thời gian RFC 3339. Phần tử updated
cho
biết khi nào chỉnh sửa sự kiện lần cuối, hoặc trong trường hợp có một sự
kiện mới, khi nào tạo ra nó.
Sau các phần tử
id
,
published
, và
updated
đến các phần tử có thông tin dễ đọc cho
mọi người hơn, như trong Liệt kê 2. Có thể hiển thị thông tin này trong
một thanh bên hoặc trang các sự kiện.Liệt kê 2. Mục nguồn cung cấp tin sự kiện mẫu của Google Calendar: tên, tác giả, và trạng thái
... ... <title type="text">Linux Install Fest</title> ... ... <author> <name>Open Source San Juan</name> <email>foss.sanjuan@gmail.com</email> </author> ... ... <gd:eventStatus value="http://schemas.google.com/g/2005#event.confirmed"/> ... ... |
Phần tử
title
(tên) là một chuỗi đơn giản để
nhận ra sự kiện đó. Nó không cần phải là duy nhất. Phần tử
author
(tác giả) chứa phần tử
name
và email
. Tác
giả của sự kiện là người dùng Google Calendar, những người đã nhập sự kiện
vào trong lịch. Với nguồn cung cấp tin có xác thực và các quyền ghi được
thiết lập phù hợp, những người dùng Google Calendar khác với người chủ sở
hữu của lịch có thể tạo các sự kiện trên lịch của người dùng khác. Bảng 1
mô tả các giá trị có thể với phần tử status
(trạng thái).Bảng 1. Các giá trị có thể với phần tử gd:eventStatus
Giá trị | Mô tả |
---|---|
http://schemas.google.com/g/2005#event.cancelled | Xóa bỏ sự kiện này. |
http://schemas.google.com/g/2005#event.confirmed | Xác nhận sự kiện này. |
http://schemas.google.com/g/2005#event.tentative | Lập lịch biểu thăm dò cho sự kiện này. |
Bây giờ đến các phần tử mô tả thời gian và địa điểm ở đó sẽ diễn ra sự kiện
này, như trong Liệt kê 3.
Liệt kê 3. Mục nguồn cung cấp tin sự kiện mẫu của Google Calendar: When và where
... ... <gd:when startTime="2007-08-03T16:00:00.000-04:00" endTime="2007-08-03T19:00:00.000-04:00"/> <gd:where valueString="Guaynabo Public High School Auditorium, Guaynabo, PR"/> </entry> |
Phần tử
when
chứa hai thuộc tính: thời gian bắt
đầu và kết thúc của sự kiện, cả hai đều theo định dạng dấu thời gian RFC
3339. Thuộc tính valueString
của phần tử
where
có đủ khả năng tìm kiếm từ ứng dụng
Google Calendar và thông qua API. Google Calendar và API dữ liệu Google
không hỗ trợ tìm kiếm bằng các phần tử riêng. Thay vào đó, chúng tìm kiếm
toàn văn bản trên các phần tử string
(chuỗi),
ví dụ như title
,
author
, description
và thuộc tính valueString
của phần tử
where
. Như bạn sẽ thấy sau này, trường hợp
ngoại lệ là API dữ liệu Google hỗ trợ các phạm vi thiết lập các ngày bắt
đầu để hạn chế các sự kiện nào được chứa trong các kết quả truy vấn.
Hạn chế các nội
dung của nguồn cung cấp tin Google Calendar
Để hỗ trợ phục hồi các tập dữ liệu chính xác, API dữ liệu Google hỗ trợ
khái niệm về các tham số truy vấn bằng yêu cầu
GET
của HTTP. Khi sử dụng các tham số này, máy
khách API dữ liệu Google có thể quy định số lượng tối đa các mục để trả về
(với tham số max-results
), phần tử nào sử dụng
để phân loại các mục trong nguồn cung cấp tin (thông qua tham số
orderby
) và toàn bộ thời gian bắt đầu và thời
gian kết thúc trong phạm vi các mục để trả về (thông qua các tham số
start-min
và
start-max
). Hai tham số cuối cùng này nói đến
phạm vi ngày của thời gian bắt đầu sự kiện được chứa trong tập kết quả các
sự kiện. start-min
nói đến ngày bắt đầu trong
phạm vi đó và start-max
nói đến ngày kết thúc
của phạm vi đó. Cả hai đều được biểu thị theo định dạng dấu thời gian RFC
3339.
Cuối cùng, bạn có thể tạo cho các sự kiện định kỳ dễ dàng hơn để phân tích
cú pháp bằng cách dùng tham số
singleevents
trong chuỗi truy vấn. Khi tham số singleevents
có một giá trị đúng, các sự kiện định kỳ được quy định trong nguồn cung
cấp tin như thể chúng đã là các sự kiện đơn lẻ khác biệt. Ngược lại, các
sự kiện định kỳ có một phần tử
<gd:recurrence>
chứa các quy tắc định kỳ
theo định dạng iCal. Định dạng iCal và cách phân tích cú pháp nó nằm ngoài
phạm vi của bài viết này.
Địa chỉ URL của nguồn cung cấp tin sự kiện trông giống như trong Liệt kê 4
với tất cả các tham số truy vấn bổ sung. Nó đã được biên tập lại để ngắt
URL dài thành một vài dòng cho dễ đọc.
Liệt kê 4. Địa chỉ URL của nguồn cung cấp tin mẫu của Google Calendar với các tham số truy vấn
http://www.google.com/calendar/feeds/foss.sanjuan%40gmail.com/public/full? max-results=25& singleevents=true& orderby=starttime& start-min=2007-05-22T09%3A58%3A47-04%3A00& start-max=2007-11-06T09%3A58%3A47-04%3A00 |
Phân tích cú pháp
nguồn cung cấp tin Google Calendar bằng PHP
Đến nay tôi đã thảo luận về các phần tử của nguồn cung cấp tin sự kiện của
Google Calendar và cách truy vấn nguồn cung cấp tin này để nhận được các
mục mà bạn đang quan tâm đến, tôi sẽ khảo sát kỹ các cách để phân tích cú
pháp nguồn cung cấp tin này và hiển thị nó trên một trang. PHP cung cấp
một số XML API mà bạn có thể sử dụng để lấy ra một danh sách các mục sự
kiện và chọn ra các tên, ngày tháng, thời gian, và địa điểm cho mỗi sự
kiện. Tôi sẽ bắt đầu với DOM API (Document Object Model – Mô hình đối
tượng tài liệu).
Phân tích cú pháp
nguồn cung cấp tin với DOM
XML DOM API là một API phân tích cú pháp-XML tiêu chuẩn, và nó được dùng
phổ biến nhất khi lập trình các ứng dụng XML. Việc sử dụng DOM API nằm
ngoài phạm vi của bài viết này, nhưng tôi sẽ xem xét kỹ một chương trình
ví dụ để phân tích cú pháp một nguồn cung cấp tin sự kiện Google Calendar
và giải thích một số lợi ích và hạn chế các DOM API.
Một lợi ích của XML DOM API là nó rất nhanh. Nó tải toàn bộ tài liệu XML
vào trong bộ nhớ, và lấy ra các phần tử từ tất cả các tài liệu XML nằm ra
trong bộ nhớ. Trong khi API này không hiệu quả với các tệp XML lớn, nó có
thể chấp nhận được với các tệp XML chỉ có 2 hoặc 3 MB.
Một lợi ích khác của XML DOM API là khả năng dễ đọc của nó. Phân tích cú
pháp XML với DOM có các lệnh để mở tài liệu XML và lấy ra các phần tử cụ
thể từ các tài liệu theo kiểu phân cấp. Nó gần giống như tiếng Anh, nói
với PHP "nhận được các phần tử với tên thẻ 'entry'". Liệt kê 5 là một ví
dụ để giải thích điều tôi muốn nói.
Liệt kê 5. Phân tích cú pháp nguồn cung cấp tin sự kiện Google Calendar bằng DOM API
<?php $confirmed = 'http://schemas.google.com/g/2005#event.confirmed'; $three_months_in_seconds = 60 * 60 * 24 * 28 * 3; $three_months_ago = date("Y-m-d\Th:i:sP", time() - $three_months_in_seconds); $three_months_from_today = date("Y-m-d\Th:i:sP", time() + $three_months_in_seconds); $feed = "http://www.google.com/calendar/feeds/foss.sanjuan%40gmail.com/" . "public/full?orderby=starttime&singleevents=true&" . "start-min=" . $three_months_ago . "&" . "start-max=" . $three_months_from_today; $doc = new DOMDocument(); $doc->load( $feed ); $entries = $doc->getElementsByTagName( "entry" ); foreach ( $entries as $entry ) { $status = $entry->getElementsByTagName( "eventStatus" ); $eventStatus = $status->item(0)->getAttributeNode("value")->value; if ($eventStatus == $confirmed) { $titles = $entry->getElementsByTagName( "title" ); $title = $titles->item(0)->nodeValue; $times = $entry->getElementsByTagName( "when" ); $startTime = $times->item(0)->getAttributeNode("startTime")->value; $when = date( "l jS \o\f F Y - h:i A", strtotime( $startTime ) ); $places = $entry->getElementsByTagName( "where" ); $where = $places->item(0)->getAttributeNode("valueString")->value; print $title . "\n"; print $when . " AST\n"; print $where . "\n"; print "\n"; } } ?> |
Trong ví dụ mã này, bạn thiết lập địa chỉ URL của nguồn cung cấp tin với
các tham số cần thiết, mở nguồn cung cấp tin, sau đó nhận được tất cả các
mục sự kiện trong một
DOMNodeList
, mà bạn có
thể xử lý bằng trình lặp foreach
. Với mỗi mục
sự kiện, bạn so sánh giá trị thuộc tính của phần tử
gd:eventStatus
với giá trị đã biết với các sự
kiện đã xác nhận. Lưu ý rằng bạn không cần chỉ rõ tiền tố
gd:
cho thẻ element
.
PHP DOM API hiểu các vùng tên, và bạn cần loại bỏ tiền tố
gd:
hoặc trình phân tích cú pháp sẽ không tìm
thấy phần tử mà bạn cần.
Nếu mục sự kiện được xác nhận, bạn lấy ra các phần tử
title
, gd:when
và
gd:where
. Các phần tử
gd:when
và gd:where
đòi hỏi bạn đưa ra các thuộc tính cụ thể, ví dụ như
startTime
và
valueString
. Bạn muốn hiển thị các ngày sự kiện
theo cách dễ đọc cho mọi người và phân tích cú pháp thuộc tính
startTime
của phần tử
gd:when
để chuyển đổi nó thành số nguyên dài
biểu diễn thời gian. Sau đó, bạn chuyển các ngày sự kiện này tới hàm date
theo định dạng hiển thị phổ biến.
Một trong những nhược điểm của DOM API là nó hơi dài dòng. Mặc dù mục đích
của mỗi câu lệnh là rõ ràng những vì nó cần phù hợp với mô tả văn bản của
thuật toán, nên câu lệnh không thể là một đoạn mã ngắn gọn hơn được. Các
phương thức
getElementsByTagName
và
getAttributeNode
với các lớp
DOMNode
và
DOMDocument
cũng làm tăng thêm kích thước đáng
kể.
Phân tích cú pháp
nguồn cung cấp tin với SAX
Một API phân tích cú pháp-XML có sẵn cho PHP là SAX API (Simple API for XML
(SAX) API – API đơn giản cho XML API). Trong khi DOM API dễ đọc và dài
dòng, thì SAX có thể ngắn gọn và khó thực hiện, ngay cả với các nhà phát
triển có kinh nghiệm. Những khác biệt giữa SAX và DOM là SAX không tải
toàn bộ tài liệu XML vào bộ nhớ, trong khi DOM làm như vậy. Mã xử lý SAX
hiệu quả có thể có tốc độ nhanh, và có thể duy trì sử dụng bộ nhớ ở mức
tối thiểu và phù hợp cho các nhu cầu cụ thể của ứng dụng. Với DOM, các yêu
cầu bộ nhớ của bạn bắt đầu từ kích thước của tài liệu XML lớn nhất cần xử
lý trong ứng dụng của bạn và từ đó tăng thêm.
Liệt kê 6 là một đoạn mã của một ví dụ về xử lý SAX của nguồn cung cấp tin
sự kiện Google Calendar. Để có ví dụ hoàn chỉnh, hãy tham khảo kịch bản
lệnh sax_sample.php trong gói các kịch bản lệnh ví dụ được cung cấp trong
phần Tải về.
Liệt kê 6. Phân tích cú pháp nguồn cung cấp tin sự kiện Google Calendar bằng SAX API
function startElement( $parser, $tagName, $attr ) { global $g_entries, $g_tagName, $g_confirmed, $g_is_confirmed, $g_in_entry, $g_in_originalevent; if ( $tagName == 'ENTRY' ) { if ($g_is_confirmed || count( $g_entries ) == 0) { $g_entries []= array(); } $g_is_confirmed = false; $g_in_entry = true; } else if ($tagName == 'GD:EVENTSTATUS') { if ($attr['VALUE'] == $g_confirmed) { $g_is_confirmed = true; } } else if ($tagName == 'GD:WHEN' && $g_is_confirmed && $g_in_originalevent == false) { $startTime = date( "l jS \o\f F Y - h:i A", strtotime($attr['STARTTIME']) ); $g_entries[ count( $g_entries ) - 1 ]['when'] = $startTime; } else if ($tagName == 'GD:WHERE' && $g_is_confirmed) { $g_entries[ count( $g_entries ) - 1 ]['where'] = $attr['VALUESTRING']; } else if ( $tagName == 'GD:ORIGINALEVENT' ) { $g_in_originalevent = true; } $g_tagName = $tagName; } function endElement( $parser, $tagName ) { global $g_tagName, $g_in_entry, $g_in_originalevent; if ( $tagName == 'ENTRY' ) { $g_in_entry = false; } else if ( $tagName == 'GD:ORIGINALEVENT' ) { $g_in_originalevent = false; } $g_tagName = null; } function textData( $parser, $text ) { global $g_entries, $g_tagName, $g_in_entry; if ($g_tagName == 'TITLE' && $g_in_entry) { $g_entries[ count( $g_entries ) - 1 ]['title'] = $text; } } |
Mã này cho thấy các hàm
startElement
,
endElement
và
textData
được đăng ký với máy của trình phân
tích cú pháp SAX trong kịch bản lệnh ví dụ SAX. Phần mã này cho thấy việc
xử lý với một số phần tử quan tâm. Mã là khá phức tạp vì trong SAX các
phần tử XML của tài liệu XML được đọc theo thứ tự từ trên xuống dưới. Bạn
không thể kiểm tra xem mục sự kiện hiện tại đã được xác nhận chưa trước
khi bạn xử lý một số phần tử bạn muốn. Ví dụ, phần tử
gd:eventStatus
đặt sau phần tử
title
trong một sự kiện. Một nguồn khác phức
tạp là nguồn cung cấp tin có phần tử title
và
mỗi mục cũng có một phần tử title
. Bạn cần
thiết lập một cờ để cho mã biết liệu bạn có đọc phần tử
title
trong mục đó không. Ngoài ra còn có phần
tử gd:when
bên trong phần tử
gd:originalEvent
trong các sự kiện định kỳ,
không có phần tử gd:when
mà bạn đang quan tâm.
Nếu không có logic kiểm tra-trạng thái này, thì việc phối hợp đơn giản các
tên phần tử sẽ tạo ra kết quả đầu ra sai.
Từ ví dụ này, bạn có thể thấy hai trong số các nhược điểm của SAX API: Nó
dài dòng hơn nhiều so với DOM API và khi được so sánh với mã mẫu DOM,
trình phân tích cú pháp SAX còn phức tạp hơn nhiều lần.
Phân tích cú pháp
nguồn cung cấp tin với các trình bao Zend Google API
Zend Technologies, cộng tác với Google, đã mở rộng Khung công tác Zend
(Zend Framework) để cung cấp một tập các lớp hướng đối tượng cho PHP, ẩn
dấu nhiều thông tin chi tiết về các nguồn cung cấp tin Atom của API dữ
liệu Google, trong khi vẫn đưa ra sự hỗ trợ cho tất cả thông tin dữ liệu
của Google. Các lớp hướng đối tượng này có nhiều lợi ích, bao gồm việc
trình bày các tài liệu API dữ liệu Google khác nhau như là các đối tượng
trừu tượng với các phương thức và các tham số đơn giản và che giấu các
thông tin chi tiết về các nguồn cung cấp tin Atom và các hành động của
giao thức HTTP, như là các
GET
, các
PUT
và các POST
. Các
lớp này cũng chứa đựng các thông tin chi tiết về xác thực người dùng trong
API dữ liệu Google, làm cho việc viết các ứng dụng hỗ trợ tất cả các tính
năng của API dữ liệu Google trở nên đơn giản hơn, chẳng hạn như việc tạo
và cập nhật các sự kiện từ một ứng dụng khách của bên thứ ba.
Trong khi điều này làm đơn giản hoá việc phát triển cho các nhà phát triển
chưa quen với phân tích cú pháp XML và các thông tin chi tiết của giao
thức HTTP, các lớp của API dữ liệu Google Zend Framework cũng có nhược
điểm của mình. Như trong Liệt kê 7, mã này dài dòng vì nhiều hàm tạo đối
tượng không có các tham số. Do đó, cần phải thiết lập các tùy chọn thông
qua các đặc tính sau khi đã tạo ra một đối tượng.
Liệt kê 7. Yêu cầu và xử lý một nguồn cung cấp tin sự kiện Google Calendar với các lớp Zend PHP
<?php require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); $three_months_in_seconds = 60 * 60 * 24 * 28 * 3; $three_months_ago = date("Y-m-d\Th:i:sP", time() - $three_months_in_seconds); $three_months_from_today = date("Y-m-d\Th:i:sP", time() + $three_months_in_seconds); // Create an instance of the Calendar service without authentication, // for read-only access to a public feed $service = new Zend_Gdata_Calendar(); $query = $service->newEventQuery(); $query->setUser('foss.sanjuan%40gmail.com'); $query->setVisibility('public'); $query->setProjection('full'); $query->setOrderby('starttime'); $query->setStartMin($three_months_ago); $query->setStartMax($three_months_from_today); // Retrieve the event list from the calendar server try { $eventFeed = $service->getCalendarEventFeed($query); } catch (Zend_Gdata_App_Exception $e) { echo "Error: " . $e->getResponse(); } // Iterate through the list of events, outputting them as an HTML list print "<ul>\n"; foreach ($eventFeed as $event) { print "<li>" . $event->title . "</li>\n"; $startTime = $event->when->startTime; print "<li>" . date("l jS \o\f F Y - h:i A", strtotime( $startTime ) ); // Google Calendar API's support of timezones is buggy print " AST</li>\n"; print "<li>" . $event->where->valueString . "</li>\n"; } print "</ul>\n"; |
Một trong những lợi ích của các lớp API dữ liệu Google Zend là sau khi đối
tượng
eventFeed
được lấy ra, các phần tử và các
thuộc tính của nguồn cung cấp tin có thể được duyệt theo phân cấp như các
thuộc tính của đối tượng eventFeed
. Theo ý kiến
của tôi, việc này cho phép dễ đọc mã xử lý hơn vì các phần tử khác nhau
được thiết lập theo mẫu tương tự như cách chúng được trình bày trong tài
liệu XML. Các thuộc tính cũng có khả năng duyệt theo kiểu phân cấp từ các
phần tử cha mẹ của chúng, không giống như phương thức
getAttributeNode("attributeName")->value
của
DOMNode.
Phân tích cú pháp
với XPath và SimpleXML
Tôi tin rằng SimpleXML API, với sự hỗ trợ của nó để truy vấn tài liệu XML
bằng cách sử dụng XPath, là một trong những API phân tích cú pháp-XML đơn
giản nhất để sử dụng. Nó chứa tài liệu XML như là một tập các đặc tính đối
tượng có phân cấp của tài liệu XML được tải. API này cũng tương tự như
cách DOM trả về các cá thể của đối tượng DOMNode, có thể duyệt theo phân
cấp. Giống như các đối tượng DOMNode của DOM và không giống như các lớp
Zend, các thuộc tính của một phần tử cần được lấy ra bằng cách gọi phương
thức
attributes()
. Phương thức này trả về một
đối tượng chứa các thuộc tính như là các đặc tính đối tượng. Liệt kê 8 nêu
ra tất cả các logic cần thiết để phân tích cú pháp và duyệt một nguồn cung
cấp lịch của API dữ liệu Google bằng SimpleXML.Liệt kê 8. Phân tích cúa pháp nguồn cung cấp tin sự kiện Google Calendar với XPath và SimpleXM
$s = simplexml_load_file($feed); foreach ($s->entry as $item) { $gd = $item->children('http://schemas.google.com/g/2005'); if ($gd->eventStatus->attributes()->value == $confirmed) { ?> <font size=+1><b> <?php print $item->title; ?> </b></font><br> <?php $startTime = ''; if ( $gd->when ) { $startTime = $gd->when->attributes()->startTime; } elseif ( $gd->recurrence ) { $startTime = $gd->recurrence->when->attributes()->startTime; } print date("l jS \o\f F Y - h:i A", strtotime( $startTime ) ); // Google Calendar API's support of timezones is buggy print " AST<br>"; ?> <?php print $gd->where->attributes()->valueString; ?> <br><br> <?php } } ?> |
Một nhược điểm với SimpleXML API của PHP là nó có thể chậm hơn nhiều nhất
đến bốn lần so với DOM hoặc SAX. Điều này xuất phát từ thực tế là
SimpleXML tạo các nút phần tử và thuộc tính trong lúc hoạt động bằng cách
lợi dụng tính chất động của PHP. Ngược lại các lớp API dữ liệu Google
Zend, định nghĩa các nút phần tử và thuộc tính trong mã lớp. Điều này làm
cho việc duyệt các nút theo phân cấp bằng các lớp Zend nhanh hơn.
Một nhược điểm nữa với SimpleXML là sự hỗ trợ của nó cho các vùng tên XML.
Để lấy ra các phần tử từ một vùng tên, cần gọi phương thức
children()
trên một phần tử. Phương thức này
trả về một đối tượng có các phần tử của vùng tên đó làm các đặc tính. DOM
và các lớp Zend cung cấp hỗ trợ tốt hơn bằng cách đưa ra tất cả các phần
tử của tất cả các vùng tên làm các nút có thể duyệt-theo phân cấp riêng lẻ
của các phần tử khác.
Xem xét hiệu năng
và lưu trữ trong bộ nhớ nhanh
Khi thảo luận về phân tích cú pháp XML trong PHP, tôi đã nói rằng SimpleXML
có thể chậm hơn nhiều lần so với việc phân tích cú pháp DOM hoặc SAX. Lý
do để chọn SimpleXML của tôi là nó dễ sử dụng hơn so với SAX và làm cho mã
phân tích cú pháp XML dễ đọc hơn DOM. Việc tạo các nút phần tử và thuộc
tính của SimpleXML trong lúc hoạt động như là các đặc tính của các nút
khác làm cho mã duyệt nút hầu như dễ đọc như các lớp API dữ liệu Google
Zend.
Tuy nhiên, mẫu mã được cung cấp trong bài viết này có vấn đề khác: Nó đòi
hỏi nguồn cung cấp tin sự kiện Google Calendar mỗi khi người dùng truy cập
vào trang đó. Nếu bạn đặt mẫu mã này vào một thanh bên trên một trang PHP,
thì mỗi khi một người truy cập vào bất kỳ các trang nào của bạn, mã
này phải tải về và phân tích cú pháp nguồn cung cấp tin. Việc này là khá
lãng phí, nếu xét ra lịch có thể không thay đổi hàng giờ hoặc thậm chí
hàng ngày. Nếu trang của bạn là phổ biến và thu hút 1000 hoặc nhiều lần
truy cập trang hơn cho mỗi ngày (dễ dàng đạt được với một diễn đàn phổ
biến chỉ với nhóm 20-30 người dùng), nguồn cung cấp tin này được yêu cầu
và được xử lý với mỗi lần truy cập trang. API dữ liệu Google có các điều
khoản dịch vụ rõ ràng giải thích rằng kiểu sử dụng này là không được phép.
Google có thể, và có lẽ, sẽ chặn địa chỉ IP của máy chủ của bạn nếu bạn
lạm dụng các điều khoản dịch vụ của nó. Tệ hơn nữa, Google có thể hủy bỏ
tài khoản của bạn. Rõ ràng, cần một cách tiếp cận thông minh hơn.
Có một vài chiến lược mà bạn có thể thực hiện để tạo cho mã mẫu này làm
việc thông minh hơn và trong phạm vi các điều khoản dịch vụ của Google
API. Tất cả đều liên quan đến việc lưu trữ thông tin cần hiển thị trong bộ
nhớ nhanh theo kịch bản lệnh và chỉ yêu cầu xử lý toàn bộ nguồn cung cấp
tin nếu và khi nó đã thay đổi. Một cuộc thảo luận chuyên sâu về các kỹ
thuật lưu trữ trong bộ nhớ nhanh nằm ngoài phạm vi của bài viết này, nhưng
tôi sẽ trình bày chúng rất ngắn gọn để cung cấp cho bạn một ý tưởng về
cách có thể cải thiện kịch bản lệnh này.
Một kỹ thuật liên quan đến việc sử dụng HTTP đòi hỏi các tiêu đề kiểm tra
xem nguồn cung cấp tin API dữ liệu Google đã thay đổi chưa. Các dịch vụ dữ
liệu Google thiết lập tiêu đề đáp ứng
Last-Modified
dựa trên giá trị của phần tử
<atom:updated>
trong thông tin được trả
về. Kịch bản lệnh, dựa vào lần gọi đầu tiên, có thể lưu trữ kết quả đầu ra
được tạo bằng cách xử lý nguồn cung cấp tin với một tệp HTML. Sau đó kịch
bản lệnh này có thể lưu giá trị của dấu thời gian
<atom:updated>
trong một bản ghi cơ sở dữ
liệu. Tiếp theo bất kỳ người dùng nào yêu cầu xem lịch sự kiện, máy khách
lấy ra dấu thời gian này và gửi nó trở lại vào tiêu đề yêu cầu
If-Modified-Since
để tránh lấy lại nguồn cung
cấp tin nếu nó vẫn chưa thay đổi.
Nếu nội dung vẫn không thay đổi kể từ thời điểm được chỉ thị trong tiêu đề
If-Modified-Since
, dịch vụ dữ liệu Google trả
về một đáp ứng HTTP
304
(Not Modified
không thay đổi). Vì đáp ứng này có nghĩa là dữ liệu sự kiện vẫn chưa thay
đổi, sau đó kịch bản lệnh có thể bao gồm tệp HTML được tạo ra trước
đó. Nếu nguồn cung cấp tin đã thay đổi, dịch vụ dữ liệu Google trả về một
đáp ứng HTTP
200
(OK)
.
Trong trường hợp này, kịch bản lệnh tái tạo nội dung mới cho tệp HTML,
thiết lập bản ghi cơ sở dữ liệu với giá trị dấu thời gian mới trong phần
tử <atom:updated>
và bao gồm tệp
HTML mới được tạo ra.
Việc lưu một dấu thời gian đơn lẻ vào một cơ sở dữ liệu đúng là hơi quá mức
một chút, nhưng PHP không hỗ trợ các biến mức-ứng dụng như các ASP (Active
Server Pages – Các trang máy chủ hoạt động) của Microsoft, Microsoft
ASP.NET, các Java servlet và các trang JavaServer (JSP) làm, ít nhất là
không có sẵn trong gói. Một giải pháp tương tự là sử dụng bộ nhớ chia sẻ.
Không phải tất cả các bản cài đặt PHP đều hỗ trợ bộ nhớ chia sẻ vì đó có
thể là một nguy cơ an toàn. Lựa chọn lưu trữ trong bộ nhớ nhanh có khả
năng khác, đặc biệt là nếu ứng dụng PHP của bạn đang chạy trong một cụm
máy chủ Web, là memcached, một dịch vụ lưu trữ-bộ nhớ có phân cụm
ban đầu được viết bởi các tác giả của LiveJournal và bây giờ được cải
thiện rộng rãi bởi các nhà phát triển của Facebook.
Kết
luận
Google Calendar cung cấp một lối vào ứng dụng Web tập trung từ đó một tổ
chức và các nhà lãnh đạo của nó có thể duy trì và xuất bản một lịch sự
kiện cho các thành viên và công chúng nói chung. API dữ liệu Google đưa ra
các nguồn cung cấp tin Atom và Giao thức xuất bản Atom để lấy ra, truy
vấn, cập nhật, và tạo ra các sự kiện và các thông tin khác bằng Google
Calendar và hầu như tất cả các ứng dụng Google khác.
Sử dụng XPath, bạn có thể tự động duy trì hiển thị trang Web với các sự
kiện sắp tới theo ngày bằng cách truy vấn các nguồn cung cấp tin sự kiện
API dữ liệu Google và phân tích cú pháp các mục của nó với các thông tin
chi tiết có liên quan giữa các phần tử của các mục. Trong khi XPath không
phải là XML API nhanh nhất trong bộ công cụ PHP, thì nó là một trong những
API đơn giản nhất để sử dụng khi bạn có một tài liệu XML đầy đủ trên tay.
Bạn có thể sử dụng lưu trữ trong bộ nhớ nhanh để giảm tác động về hiệu
năng tương đối chậm của XPath.
Tải về
Mô tả | Tên | Kích thước | Phương thức tải |
---|---|---|---|
Sample PHP code | os-php-xpath.google-calendar-api.zip | 4KB | HTTP |
Tài nguyên
Học tập
- Tìm hiểu thêm về hệ thống quản lý nội
dung Drupal tại trang Web của
nó.
-
Tổng quan về
các Google Calendar API và các công cụ có chứa một giới thiệu tốt
về các cách sử dụng có khả năng của Google Calendar API và các liên kết
đến tài liệu hướng dẫn cẩn thận hơn về tất cả các phần của API.
-
PHP.net là tài nguyên chủ yếu cho các nhà
phát triển PHP.
- Xem "Danh sách khuyến khích đọc
PHP."
- Duyệt tất cả nội dung PHP trên developerWorks.
- Mở rộng các kỹ năng PHP của bạn bằng cách
đọc các tài nguyên dự án PHP trên
developerWorks của IBM.
- Để nghe các cuộc phỏng vấn và các cuộc
thảo luận thú vị dành cho các nhà phát triển phần mềm, hãy vào developerWorks
podcasts.
- Có nên sử dụng một cơ sở dữ liệu với PHP
không? Hãy đọc Zend Core
với IBM, một môi trường sản xuất và phát triển PHP dễ cài đặt,
ngoài hộp, liên tục để hỗ trợ IBM DB2 V9.
- Theo sát với các sự kiện kỹ thuật và các
Webcast của developerWorks.
- Xem các hội nghị, triển lãm thương mại,
Webcast sắp tới và Các sự kiện khác trên thế giới
được các nhà phát triển nguồn mở của IBM quan tâm.
- Truy cập vào Vùng mã nguồn mở của
developerWorks với các thông tin hướng dẫn rộng lớn, các công cụ và các
bản cập nhật dự án để giúp bạn phát triển bằng các công nghệ mã nguồn mở
và sử dụng chúng với các sản phẩm của IBM.
- Xem và tìm hiểu về IBM và các công nghệ
mã nguồn mở và các chức năng sản phẩm với các trình diễn theo yêu cầu miễn
phí của developerWorks.
Lấy sản phẩm và công nghệ
-
Nguồn cung cấp tin sự kiện Google Calendar của San Juan nguồn mở,
đó là nguồn cung cấp tin sự kiện giả thường dùng trong các ví dụ mã trong
bài viết này.
- Đổi mới dự án
phát triển nguồn mở tiếp theo của bạn bằng phần mềm dùng thử của IBM, có
sẵn để tải xuống hoặc trên đĩa DVD.
- Tải về các phiên bản đánh giá sản phẩm IBM, và nhận được các công cụ phát triển ứng dụng thực hành của bạn và các sản phẩm phần mềm trung gian từ DB2®, Lotus®, Rational®, Tivoli®, và WebSphere®.
Nguồn IBM
0 comments:
Post a Comment