Ultimate mashup – Các dịch vụ Web và Web ngữ nghĩa (semantic Web), Phần 6: Sử dụng kết hợp các dịch vụ Web

Khám phá các khái niệm về Mashup và xây dựng một Mashup đơn giản.

Khi dịch vụ Web phát triển rộng rãi, các công ty dịch vụ Web và các nhà phát triển ứng dụng web đã tạo ra những sáng kiến mới cùng với các dữ liệu của chúng, bổ sung vào các ứng dụng đơn lẻ. Các nhà phát triển ứng dụng đang tạo ra các Mashup, các ứng dụng kết hợp dữ liệu từ nhiều loại dịch vụ để tạo ra những điều mới mẻ. Loạt bài này trình bày sự hình thành Mashup căn bản theo trình tự thời gian, một ứng dụng mà không chỉ lưu dữ liệu từ các Mashup khác nhau mà còn sử dụng các kỹ thuật ngữ nghĩa cho phép người dùng tạo ra Mashup của riêng họ bằng cách thay đổi các dịch vụ hay thậm chí bằng cách chọn các dữ liệu. Phương pháp này dùng trình Java (TM)™ kết hợp các servlet, JSP, dự án mã nguồn mở Jena và các khả năng mới XML của DB2. Ở phần này Nicholas Chase giới thiệu các khái niệm Mashup, cho bạn thấy các thức hoạt động của chúng và cách xây dựng một phiên bản Mashup đơn giản.

Nicholas Chase, Tác giả tự do, Site Dynamics Interactive Communications

Nicholas Chase đã phát triển trang web cho các công ty lớn như Lucent Technologies, Sun Microsystems, Oracle, và Tampa Bay Buccaneers. Nick đã từng là một giáo viên vật lý ở trường phổ thông, một nhà quản lý thiết bị phóng xạ mức thấp, một nhà biên tập tạp chí khoa học viễn tưởng trực tuyến, một kỹ sư đa phương tiện, một hướng dẫn của Oracle, và một trưởng phòng công nghệ của một công ty tương tác truyền thông. Nick là tác giả của một số sách



08 03 2007 (Xuất bản lần đầu tiên vào ngày 20 05 2009)

Trước khi bạn bắt đầu

Bài viết này dành cho các nhà phát triển muốn học thêm về cách sử dụng và kết hợp các dịch vụ Web từ góc độ XML, và cách xuất các dữ liệu đó lên Web. Tất cả các dịch vụ được thảo luận ở trong bài viết đều là các dịch vụ REST nhưng các khái niệm tương tự như đối với các dịch vụ SOAP. Bài viết này xem như bạn có kiến thức cơ bản về lập trình Java™ XML, phát triển Web, và các khái niệm cơ bản về các dịch vụ Web. Nếu bạn cần tìm hiểu lại ba chủ đề này hãy xem tài nguyên để biết thêm chi tiết.

Về các bài viết này

Dường như bạn không thể vào Web mà không vào một trang Web hoặc là cung cấp cho bạn quyền truy cập dữ liệu của nó thông qua hàm API dựa trên dịch vụ web (Web-services-based API) hoặc là sử dụng dữ liệu từ trang web khác lấy từ một API dựa trên dịch vụ web. Khi bạn xem xét lợi thế của việc sử dụng các thông tin sẵn có trong ứng dụng của riêng bạn thì điều đó không hề gây ngạc nhiên. Đây chỉ là vấn đề thời gian trước khi ai đó bắt đầu kết hợp dữ liệu từ các hệ thống khác nhau để tạo ra một thứ hoàn toàn mới. Những ứng dụng này được gọi là các Mashup, là hiện tượng thịnh hành nhất trên Web, từ các trang cộng đồng (community-based) đến các trang tìm kiếm đặc biệt, và tới các Mashup từng xuất hiện.

Hầu hết các Mashup rất hữu ích, nhưng chúng có một đặc điểm chung là chúng được tạo ra cho một loạt các dịch vụ riêng biệt, và nếu một trong các dịch vụ đó thay đổi hoặc dịch vụ riêng biệt của một loại hình cụ thể nào đó thay đổi thì bạn sẽ có nhiều việc phải làm với nó.

Mục đích của loạt bài viết này nhằm tạo ra một ứng dụng Mashup tốt đến mức mà người dùng có thể thêm hoặc bớt các dịch vụ nếu muốn, và hệ thống sẽ biết cách giải quyết vấn đề này. Quá trình thực hiện sẽ diễn ra như sau:

Ở phần 1 giới thiệu khái niệm các Mashup, trình bày cách ứng dụng hoạt động và xây dựng một phiên bản đơn giản nhất của một Mashup. Những sự cố trình bày nghiêm trọng liên quan tới việc tạo ra hàng loạt các cuộc gọi trên Web cũng sẽ được chỉ ra.

Ở phần 2, bạn giải quyết một số vấn đề bằng cách sử dụng tính năng mới pureXML của DB2 để xây dựng một thẻ XML để lưu giữ các yêu cầu trước đó và cũng để cho phép bạn truy lục các thông tin cụ thể.

Về cơ bản, bạn sẽ cần dùng các bản thể luận (ontologies), hoặc các từ vựng để định nghĩa các khái niệm và mối quan hệ giữa chúng, vì thế ở phần 3 bạn bắt đầu tiến trình này bằng cách tìm hiểu về RDF và RDFs, hai thành phần cơ bản nhất trong từ ngôn ngữ Web (OWL) sẽ được đề cập đến trong phần 4. Ở phần 5 bạn lấy các bản thể luận mà bạn tạo được ở phần 4 và sử dụng nó để cho phép người dùng thay đổi nguồn gốc thông tin.

Phần 6 có thể nói là rất hấp dẫn đối với bạn. Ở đây, bạn có một ứng dụng đang chạy và một khung làm việc để hệ thống có thể sử dụng lập luận ngữ nghĩa để hiểu các dịch vụ tại điểm sử dụng của nó. Ở phần này, bạn cung cấp cho người dùng quyền kiểm soát, cho phép người dùng lựa chọn dịch vụ trong bản thể luận và chọn ra các dữ liệu để dùng cho một Mashup thông thường.

Về bài viết này

Thông qua bài viết này bạn sẽ học được cách tạo một ứng dụng để có thể truy lục và hiển thị các thông tin dịch vụ Web từ một đặc điểm chung nào đó. Nói cách khác, việc thêm các dịch vụ mới chính là một phần thực hành cấu hình còn hơn cả lập trình.

Bài viết này hướng dẫn bạn cách:

  • Yêu cầu dữ liệu từ một dịch vụ Web REST

  • Dễ dàng xâu chuỗi dữ liệu XML để xuất hay hiển thị

  • Tạo một khuôn mẫu XML và sau đó thay thế các phần tử và các thuộc tính đã định trước bằng các dữ liệu động.

  • Thêm các nút XML từ các loại văn bản vào một loại văn bản xuất

  • Tạo một hệ thống hiện thị nhiều dịch vụ Web.

  • Tạo một hệ thống mà ở đó một dịch vụ Web có thể cung cấp thông tin dựa trên dữ liệu xuất của một dịch vụ Web thứ hai

Bài viết này sử dụng ngôn ngữ Java nhưng các khái niệm thì giống các ngôn ngữ lập trình và hệ điều hành khác.

Các điều kiện tiên quyết

Bạn cần phải cài đặt và kiểm tra các phần mềm sau đây nhằm tuân theo các mã trong bài viết này

  • Apache Tomcat hoặc các công cụ servlet khác: Bài viết này giả định rằng bạn sẽ xây dựng các ứng dụng Web sử dụng các servlet, vì thế bạn sẽ cần có công cụ servlet như là Apache Tomcat. Nếu bạn chọn cách xây dựng ứng dụng sử dụng môi trường khác thì hãy đảm bảo chắc chắn rằng bạn có phần mềm thích hợp trong tay. Hãy tải phần mềm apache-tomcat-5.5.17.zip và cài đặt nó vào trong một thư mực bất kỳ (Chú ý: không để dấu cách khi viết tên thư mục).
  • Java: bài viết này được xây dựng cùng Apache Tomcat 5.5, cần có Java 1.5 hoặc các phiên bản mới hơn. Tải phần mềm J2SE SDK.
  • Để tiến hành công việc thuận lợi hơn bạn có thể sử dụng một IDE như Eclipse hoặc IBM ®Rational™ Web Developer cho việc khai thác của bạn. Bạn có thể tải Eclipse tại Eclipse.org tải phiên bản thử nghiệm của Rational Web Developer hoặc dùng môi trường khai thác thông dụng của bạn. Bạn sẽ không thể làm được gì thú vị trừ khi liên quan tới tài liệu thu thập và sự triển khai của mình.

Ở các phần 2, 4, 5, và 6 của loạt bài viết bạn sẽ cần:


Tổng quan

Trước khi bắt tay vào với công việc này bạn hãy tìm hiểu qua xem bạn đang cố gắng làm điều gì.

Tại sao lại là các dịch vụ Web?

Hãy tin rằng bạn có thể định nghĩa được chúng, các dịch vụ Web đã từng là một vấn đề rất nổi cộm cách đây hơn một thập kỷ nhưng bây giờ thậm chí bạn còn được nghe đến nhiều hơn thế, đặc biệt là trên các trang Web. Tại sao lại thế? Vì nó liên quan tới mức độ phát triển của Web tại thời điểm này.

Các dịch vụ Web là cách gửi thông tin qua lại giữa các máy chủ ở các mạng khác nhau. Trong hầu hết các trường hợp, các thông tin qua lại là XML, chính XML cung cấp một hệ điều hành và một bộ dữ liệu ngôn ngữ lập trình riêng biệt. Nói cách khác, một máy chủ chạy một ứng dụng Perl trên Linux có thể gửi thông tin thông qua Internet tới một máy chủ chạy ứng dụng Java trên Windows, và hiển nhiên cả hai bên đều hiểu các thông tin này.

Lý do mà dịch vụ Web trở nên quan trọng là thế hệ mà theo một câu thần chú Ấn độ "Thông tin cần được tự do" đã biến một sinh viên thất nghiệp chỉ trong một đêm trở thành một một nhà phát kiến trong ngành công nghiệp thông tin. Điều này dẫn tới một suy nghĩ là nếu ứng dụng Web của bạn không có một hàm API dựa trên các dịch vụ web để cho phép các dịch vụ khác sử dụng các dữ liệu của bạn thì bạn sẽ bị coi là lạc hậu, và có lẽ là một kẻ đáng nghi. Đôi khi điều tệ nhất bạn có thể nói về một trang Web hay một ứng dụng là "Dịch vụ Web thật tuyệt vời nhưng chúng cũng là một khu vườn được rào kín"

Và cuối cùng, một ứng dụng sẽ không được coi là tốt trừ khi nó để cho tất cả mọi người có thể dùng nó thông qua các loại API.

SOAP với REST và XML-RPC

Bạn có một API nhưng không có nghĩa là API này giống API của những người khác. Có khá nhiều lựa chọn tồn tại và không có chuẩn riêng biệt nào được chọn ra mặc dù tính phổ biến của một loại API hay các thay đổi trong các quan điểm thông thường (thường là lựa chọn của chuyên viên thiết kế). Trong nhiều trường hợp, một ứng dụng cho phép truy cập thông qua một hoặc nhiều loại API.

Tại thời điểm này, các dạng API thông dụng nhất là:

  • REST: Mặc dù không phải là dạng xuất hiện đầu tiên nhưng REST nhanh chóng trở nên phổ biến vì sự đơn giản của nó. Tất cả những gì cần để thực hiện được một yêu cầu chỉ là một URL. XML sẽ được gửi đáp trả tới một yêu cầu HTTP, giống như một trang Web.
  • SOAP: Giao thức là phương tiện chính ở đây, SOAP cung cấp thẳng cách đưa ra một yêu cầu nhưng cách này hơi mạnh so với API. Và cách này cũng khá phức tạp khi sử dụng. Có nghĩa là, có nhiều loại bộ dụng cụ để làm cho tiến trình dễ dàng hơn và các dụng cụ như là bộ chuyển đổi ngôn ngữ mô tả dịch vụ Web sang mã nguồn tạo cho SOAP là một lựa chọn phổ biến.
  • XML-RPC: Hơi phức tạp hơn REST nhưng lại đơn giản hơn SOAP, XML-RPC là một lựa chọn thích hợp cho các nhà lập trình thích phong cách Remote Procedure Call (Gọi thủ tục điều khiển từ xa) của nó.
  • JavaScript: Xu hướng mới nhất sử dụng API cho các ứng dụng mang lại một thư viện miễn phí JavaScript là cách duy nhất để truy cập dữ liệu. Cách làm này cho phép mọi người để dữ liệu trên các trang Web của họ một cách dễ dàng nhưng lại hạn chế việc tích hợp với các dịch vụ khác. Trong vài trường hợp, các dữ liệu từ các dịch vụ khác có thể được cung cấp cho JavaScript API, nhưng cung cấp dữ liệu từ JavaScript API tới các dịch vụ khác rất khó, có khi là không thể. Nghĩa là, tìm kiếm các giới hạn này được gọi là "vườn rào kín" và để truy cập làm nhẹ đi bớt phần nào những hạn chế.

Bây giờ, trừ một số trường hợp JavaScript APIs ngoại lệ, tất cả các APIs này đều dựa trên khái niệm gửi XML tới một yêu cầu, nghĩa là nếu bạn xây dựng ứng dụng của bạn trên ý tưởng XML nhận, về căn bản bạn sẽ có khả năng sử dụng tất cả mọi thứ.

Để mọi thứ đơn giản hơn chúng ta hãy dùng REST, mặc dù các khái niệm này có thể áp dụng cho bất kỳ ba lựa chọn đầu tiên nào.

Mashup là gì?

Mục đích cuối cùng của tất cả các thông tin đưa ra ở đây là giúp cho người dùng có thể sử dụng các thông tin đó. Trong một số trường hợp nó có thể không diễn ra hoàn toàn theo như ý bạn muốn. Ví dụ, Amazon Light chứa danh sách các sản phẩm do Amazon.com bán (xem Tài nguyên), nhưng nó lại kết hợp các danh sách đó với các dữ liệu lấy từ Google, Yahoo!, Del.icio.us, Blogger, và thậm chí cả DropCash. ActorTracker (xem tài nguyên) kết hợp Amazon, eBay, và các dữ liệu chuyển đổi khác. ChicagoCrime.org công khai các số liệu trên một bản đồ của Google.

Thậm chí bạn có thể theo kịp các Mashup mới bằng việc đọc (hay đặt mua) MashupFeed.com, ở đó có liệt kê danh sách các Mashup mới được ưa chuộng bằng API. Ở đó cũng có một danh sách dài các API có sẵn để tương tác với các Mashup mới trong trường hợp bạn muốn tạo Mashup của riêng mình.

Nói một cách cơ bản, một Mashup là một sự kết hợp thông in từ một hay nhiều nguồn, trộn chúng lại theo cách bạn sẽ tạo ra một thứ mới mẻ hơn hoặc có ích hơn.

Mục đích toàn diện

Một điều mà các Mashup này chung nhau đó là chúng được tạo ra theo một mục đích nhất định với rất nhiều sự lựa chọn - ví như loại dịch vụ nên dùng cách truy cập dữ liệu, v.v..- đều được mã hóa trong ứng dụng. Mục đích của bạn là thay đổi chúng. Bạn muốn tạo một ứng dụng cho phép người dùng tự đưa ra lựa chọn của mình hay chuyển từ Google sang Yahoo!, hay từ Barnes và Noble sang Amazon.com.

Bạn cũng muốn người dùng có khả năng tạo ra diều gì đó hoàn toàn mới mẻ mà không phải lập trình.

Để điều đó xảy ra bạn cần làm một số việc sau:

  1. Tạo một cấu trúc linh hoạt cho Mashup của bạn cho phép các dịch vụ có thể được thay đổi dễ dàng.
  2. Tạo một hệ thống lưu giữ cho phép bạn dễ dàng lưu và trộn dữ liệu.
  3. Tạo một bản thể luận cho phép ứng dụng hiểu các dữ liệu mà nó đang xử lý. Nói cách khác, ứng dụng đó hiểu một giá trị hoặc một vị trí là gì, ít nhất là trong mối tương quan với các dữ liệu khác.
  4. Tìm cách sử dụng bản thể luận đó một cách có hệ thống.
  5. Cho người dùng cách tương tác với các dữ liệu khác để tạo ra các Mashup mới.

Bạn sẽ có thể làm được tất cả những việc này trong loạt bài viết này.

Những việc cần làm đầu tiên

Trong bài viết này, để bắt đầu tiến trình đó bạn sẽ tạo một Mashup nhỏ để thực hiện các đặc điểm này.

Đầu tiên, bạn hiển thị các thông tin cơ bản do một dịch vụ REST gửi lại. Sau đó bạn sẽ tiếp tục tạo một khuôn mẫu XML cho phép bạn kiểm soát xem từng kết quả REST sẽ hiện ra như thế nào.

Từ đây, bạn sẽ mở rộng hệ thống một cách đơn giản để hiển thị thông tin từ nhiều dịch vụ khác nhau. Ví dụ, bạn sẽ thấy kết quả từ cả Yahoo! và Flickr.

Cuối cùng, bạn sẽ cho phép hệ thống trình bày nhiệm vụ phức tạp hơn của Mashup khi hiển thị thông tin từ một API dựa trên thông tin do một API khác gửi lại. Ví dụ, bạn sẽ cung cấp URLs do Yahoo! gửi trả lại tới dịch vụ Web Technorati để kiểm tra xem có bao nhiêu mục trên trang thông tin cá nhân (blog) đề cập tới từng URL.

Chúng ta cùng bắt đầu.


Lấy thông tin từ một đường dẫn XML

Bây giờ bạn đã thiết lập được mọi thứ, bạn có thể bắt đầu tạo một Mashup thực sự. Bạn sẽ bắt đầu bằng cách lấy thông tin từ một tệp XML lưu trữ trên ổ cứng.

Dữ liệu mẫu

Tôi bắt đầu với một tệp XMLTV sẵn có trong ổ cứng của mình. Dữ liệu này cung cấp thông tin chi tiết về các kênh và chương trình TV cùng với các thông tin và kế hoạch cho mỗi chương trình. Vì tệp hoàn chỉnh nhiều hơn 10MB nên tôi chỉ trích ra một mẫu nhỏ. Bạn có thể thấy cấu trúc này trong ví dụ 1.

Ví dụ 1. Dữ liệu mẫu
 <?xml version="1.0"
          encoding="ISO-8859-1"?> <tv source-info-url="http://labs.zap2it.com/"
          source-info-name="TMS Data Direct Service" generator-info-name="XMLTV"
          generator-info-url="http://www.xmltv.org/"> <programme start="20060714043000
          -0400" stop="20060714050000 -0400" channel="I21883.labs.zap2it.com"> <title
          lang="en">Flintstones</title> <sub-title lang="en">The
          Gravelberry Pie King</sub-title> <desc lang="en">Fred gets
          fired and enters the pie-baking business.</desc> <credits>
          <actor>Alan Reed</actor> <actor>Jean Vander
          Pyl</actor> <actor>Mel Blanc</actor>
          <actor>Gerry Johnson</actor> <actor>Don
          Messick</actor> </credits>
          <date>19651112</date> <category
          lang="en">Children</category> <category
          lang="en">Animated</category> <category
          lang="en">Series</category> <episode-num
          system="dd_progid">EP001648.0149</episode-num> <episode-num
          system="onscreen">65149</episode-num> <subtitles
          type="teletext" /> <rating system="VCHIP">
          <value>TV-G</value> </rating>
          </programme> <programme start="20060714050000 -0400"
          stop="20060714053000 -0400" channel="I21883.labs.zap2it.com"> <title
          lang="en">Dastardly &amp; Muttley</title> <sub-title
          lang="en">Muttley On the Bounty</sub-title> <category
          lang="en">Children</category> <category
          lang="en">Animated</category> <category
          lang="en">Series</category> <episode-num
          system="dd_progid">EP001168.0006</episode-num> <episode-num
          system="onscreen">6901</episode-num> <rating
          system="VCHIP"> <value>TV-G</value>
          </rating> </programme> <programme start="20060714053000
          -0400" stop="20060714060000 -0400" channel="I21883.labs.zap2it.com"> <title
          lang="en">Banana Splits</title> ... </programme>
          </tv>

Đây là một tệp XML thông thường gồm có một phần tử gốc và một số các phần tử mẫu tin. Trong trường hợp này các phần tử mẫu tin là các phần tử lập trình. Tôi muốn lặp đi lặp lại từng phần tử này và hiển thị thông tin cụ thể.

Tách dữ liệu

Đầu tiên tách tài liệu thành bộ nhớ để bạn có thể làm việc với chúng, như ở ví dụ 2.

VÍ dụ 2. Tách văn bản (tài liệu)
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class SimpleClient {
        
   public static void main(String[] args) {

      try {

         DocumentBuilder builder =         
            DocumentBuilderFactory.newInstance().newDocumentBuilder();
         Document document = builder.parse(
                    new File("/SW/xmltv-0.5.44-win32/sample.xml"));
      
      } catch (Exception e){
      
         e.printStackTrace();
      }
   }
}

Ứng dụng này không khó. Nó tạo ra một lớp để tách tệp trên hệ điều hành cục bộ thành một đối tượng văn bản mà bạn có thể vận dụng sau này. Dĩ nhiên trong một môi trường sản xuất bạn có thể tạo ra nhiều trường hợp ngoại lệ có thể vận dụng trong trường hợp này hoặc các trường hợp khác sau này tốt hơn những gì tôi tiến hành ở đây. Nhưng đây không phải là môi trường sản xuất và chúng ta cũng không phải làm ra nhiều trường hợp như thế.

Trước đây, bạn có thể làm theo cách của mình là dùng đối tượng Document đó để tìm các nút cố định. May thay, bây giờ bạn không phải làm thế nữa.

Giới thiệu XPath

Mỗi văn bản XML đều có cấu trúc, trước đây để xử lý từng văn bản bạn cần làm theo kiểu cây, sử dụng một trong các mẫu đối tượng văn bản hoặc dùng một API dựa vào sự kiện (event-based) như là SAX để tìm thông tin bạn cần.

Nhưng việc đó thật buồn cười, đặc biệt là đối với những nhà phát triển ứng dụng quen làm việc với các phép biến đổi XML (XSL transformations) và các trang theo phong cách của họ cho phép các nhà phát triển cụ thể hóa một nút hoặc một nhóm các nút bằng việc sử dụng biểu thức XPath. Hãy xem ví dụ về biểu thức XPath ở ví dụ 3.

Ví dụ 3. Biểu thức XPath
/tv/programme 
//rating
//programme/@start 
//title[@lang='en']

Chúng cụ thể hóa bất kỳ chương trình sản phẩm của phần tử tivi, bất kỳ phần tử được sắp xếp ở đâu trong văn bản (hai nét gạch chéo (//) biểu thị sự tiếp nối của nút hiện thời, trong trường hợp này lại là một phần tử gốc) thuộc tính đầu tiên của bất kỳ phần tử lập trình nào và bất kỳ thuộc tính đầu đề đều có một thuộc tính ngôn ngữ tương đương với en.

May mắn là ngày nay bạn không phải dùng tới các thủ thuật như là tạo một chuyển đổi XML để sử dụng biểu thức XPath. Trong ứng dụng này bạn sẽ dùng chúng trực tiếp từ ứng dụng Java của bạn để lấy bất kỳ thông tin nào bạn cần.

Đánh giá một biểu thức XPath

Mục đích của bạn là lặp đi lặp lại mỗi phần tử lập trình trong văn bản, vì thế bước đầu tiên là bạn tạo một biểu thức XPath đại diện cho các phần tử lập trình này và đánh giá biểu thức đó, như bạn sẽ thấy trong ví dụ 4.

Ví dụ 4. Đánh giá biểu thức XPath
...
import java.io.File;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathConstants;
import org.w3c.dom.NodeList;

public class SimpleClient {
        
   public static void main(String[] args) {

      try {

         DocumentBuilder builder = 
           DocumentBuilderFactory.newInstance().newDocumentBuilder();
         Document document = builder.parse(
              new File("/SW/xmltv-0.5.44-win32/sample.xml"));
      
         XPath xpath = XPathFactory.newInstance().newXPath();
         String expression = "//programme";

         NodeList recordNodes = 
                (NodeList) xpath.evaluate(
                     expression, document, XPathConstants.NODESET);

         System.out.println("The result has "+
                                recordNodes.getLength()+" nodes");
         
      } catch (Exception e){
      
         e.printStackTrace();
      }
   }
}

Đầu tiên tạo ra lớp XPath từ một XpathFactory. Khi bạn đã tạo được lớp đó rồi, bạn có thể dùng phương thức evaluate() để lấy một NodeList của các nút tương ứng bằng cách cung cấp cho nó biểu thức XPath đại diện cho các nút bạn cần, cung cấp văn bản để tìm các nút, và loại dữ liệu mà bạn muốn nhận được.

Tham số cuối cùng này rất quan trọng. Trong trường hợp này bạn gửi lại một bộ các nút nhưng có thể báo cho phương thức biết rằng bạn chỉ muốn một nút mà thôi hoặc chỉ là một giá trị Boolean để báo cho bạn biết biểu thức đó có đại diện cho bất kỳ một nút thực nào không.

Khi bạn nhận lại dữ liệu bạn nên xem chúng như một đối tượng NodeList bạn vừa truy lục được bằng cách nào đó. Bạn có thể thấy rằng đoạn mã cần có số lượng các nút, như cách bạn tiến hành với NodeList lấy được thông qua phương thức getChildNodes() của DOM.

Nếu bạn chạy ứng dụng bằng tệp lệnh hoặc từ Eclipse hay IDE khác, bạn sẽ thấy đầu ra (output) báo cho bạn biết có bao nhiêu phần tử lập trình có trong mỗi văn bản, như ở ví dụ 5.

Ví dụ 5. Chạy ứng dụng
 Kết quả có 12 nút

Tạo văn bản xuất (output)

Bạn có thể chạy qua từng văn bản và xuất từng phần dữ liệu riêng biệt nhưng việc này làm bạn bị vướng lại với từng định dạng, phương thức hiển thị cụ thể, v.v... Thay vì thế, bạn sẽ tạo một văn bản xuất, một văn bản XML để bạn có thể bổ sung thông tin bạn muốn xuất. Sau đó bạn có thể xuất tới nơi mà bạn chọn.

Ở ví dụ 6, bắt đầu bằng việc tạo ra một đối tượng văn bản thực.

Ví dụ 6. Tạo văn bản xuất (output Document)
...
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import java.io.StringReader;

public class SimpleClient {
   
   public static void main(String[] args) {

      try {
...
         NodeList recordNodes = (NodeList) xpath.evaluate(
                expression, document, XPathConstants.NODESET);
         System.out.println("The result has "+
                                recordNodes.getLength()+" nodes");
         
         Document hostDoc = builder.parse(
                new InputSource(new StringReader("<div />")));
         Node hostRoot = hostDoc.getDocumentElement();
         
      } catch (Exception e){
      
         e.printStackTrace();
      }
   }
}

Bước đầu tiên là tạo một đối tượng Ducument và để làm điều này bạn tiến hành tách một văn bản XML có một loại trình tiện ích (shell), trong trường hợp này là element div để bạn đặt dữ liệu vào đó. Thay vì dùng một tệp thực, bạn có thể dùng StringReader và một InputSource để tạo một đối tượng Document ngoài String.

Khi bạn có Document, bạn cần tham khảo phần tử gốc của nó để bổ sung dữ liệu.

Chuyển các nút từ văn bản này tới văn bản khác.

Bây giờ bạn có thể lấy một Node từ một Document và bổ sung nó vào một Document khác. Bây giờ, dẫu sao cũng không tránh khỏi các lỗi thực tế xuất hiện. Bạn cần phải nhập thông tin để chuyển nó từ văn bản nguồn đến văn bản xuất một cách an toàn như bạn có thể nhìn thấy trong ví dụ 7.

Ví dụ 7. Chuyển các nút từ văn bản này tới văn bản khác.
...
         NodeList recordNodes = (NodeList) xpath.evaluate(
                  expression, document, XPathConstants.NODESET);
         System.out.println("The result has "+
                                recordNodes.getLength()+" nodes");
         
         Document hostDoc = builder.parse(
                    new InputSource(new StringReader("<div />")));
         Node hostRoot = hostDoc.getDocumentElement();
         
         for (int i=0; i < recordNodes.getLength(); i++) {

            Node importedNode = 
                    hostDoc.importNode(recordNodes.item(i), true);
            hostRoot.appendChild(importedNode);
            hostRoot.appendChild(hostDoc.createTextNode("\n"));
            
         }
        
      } catch (Exception e){
      
         e.printStackTrace();
      }
   }
}

Đối với mỗi Node ở trong NodeList, dùng phương thức importtNode của hostDoc để tạo ra bản sao của Node thuộc về hostDoc. Tham số thứ hai báo cho ứng dụng biết liệu có thực hiện một bản sao deep hay không. Nói cách khác, bằng cách cố định giá trị đó đúng, bạn báo rằng bạn không chỉ cần programme elements (phần tử lập trình) mà còn cần cả các sản phẩm khác của element (phần tử).

Khi bạn đã nhập bản sao đó vào hostDoc, bạn có thể nối nó vào hostRoot. Sau đó bổ sung một nút dòng văn bản đơn giản để kết quả dễ đọc hơn.

Xuất kết quả

Để xuất kết quả bạn sẽ phải dùng một thủ thuật XSLT-related cũ để xâu chuỗi nó tới dòng lệnh, như trong ví dụ 8.

Ví dụ 8. Xuất kết quả
import java.io.StringReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class SimpleClient {
...
         for (int i=0; i < recordNodes.getLength(); i++) {

            Node importedNode = 
                    hostDoc.importNode(recordNodes.item(i), true);
            hostRoot.appendChild(importedNode);
            hostRoot.appendChild(hostDoc.createTextNode("\n"));
            
         }

         DOMSource source = new DOMSource(hostDoc);
         StreamResult result = new StreamResult(System.out);
         TransformerFactory transFactory = 
                           TransformerFactory.newInstance();
         Transformer transformer = transFactory.newTransformer();
         transformer.transform(source, result);   
         
      } catch (Exception e){
      
         e.printStackTrace();
      }
   }
}

Đầu tiên bạn tạo một DOMSource ngoài Document mà bạn muốn xuất. Sau đó tạo một StreamResult đại diện cho dòng lệnh đó. Từ đây, tạo một newTransformer, nhưng đừng cung cấp cho nó một tờ mẫu (style sheet) bởi vì bạn muốn Document không bị thay đổi. (Đây là một trong những tiện ích của phương thức xuất này. Nếu sau đó bạn quyết định chuyển dữ liệu trước khi xuất thì việc bổ sung một tờ mẫu vào tiến trình cũng là việc bình thường)

Kết quả

Bạn có thể thấy kết quả xuất như trong ví dụ 9.

Ví dụ 9. Kết quả văn bản xuất

Nhấp vào để xem mã nguồn

Ví dụ 9. Kết quả văn bản xuất

Kết quả có 12 nút 
<?xml version="1.0" encoding="UTF-8"?><div><programme
  channel="I21883.labs.zap2it.com" start="20060714043000 -0400" 
  stop="20060714050000-0400"> 
    <title lang="en">Flintstones</title>
    <sub-title lang="en">The Gravelberry Pie King</sub-title>
    <desc lang="en">Fred gets fired and enters the pie-baking
business.</desc> 
    <credits> 
      <actor>Alan Reed</actor> 
      <actor>Jean Vander Pyl</actor>
      <actor>Mel Blanc</actor> 
      <actor>Gerry Johnson</actor> 
      <actor>Don Messick</actor>
    </credits> 
    <date>19651112</date>
    <category lang="en">Children</category> 
    <category lang="en">Animated</category> 
    <category lang="en">Series</category> 
    <episode-num system="dd_progid">EP001648.0149</episode-num> 
    <episode-num system="onscreen">65149</episode-num> 
    <subtitles type="teletext"/> 
    <rating system="VCHIP">
       <value>TV-G</value> 
     </rating>
     </programme> 
     <programme channel="I21883.labs.zap2it.com" start="20060714050000 -0400" stop="20060714053000 -0400"> 
     <title lang="en">Dastardly &amp; Muttley</title> 
     ...
     </programme> <programme channel="I21883.labs.zap2it.com"
          start="20060714053000 -0400" stop="20060714060000 -0400"> 
     <title lang="en">Banana Splits</title> 
     ... 
     </programme> 
     ...
     </div>

Lưu ý rằng bạn vẫn còn câu lệnh xuất gốc, và dữ liệu vẫn không hề thay đổi, ngoại trừ bây giờ dữ liệu nằm ở element.

Trong phần tiếp theo bạn sẽ tìm hiểu cách thay đổi cấu trúc của dữ liệu đã xuất bằng cách sử dụng các khuôn mẫu có dạng XML (XML-based).


Dùng khuôn mẫu để làm mọi thứ đồng nhất

Đến đây bạn đã xem xét cách truy lục một văn bản XML, tìm các bản ghi riêng lẻ và xuất chúng ra. Tất cả đều trôi chảy nhưng về lâu dài tốt nhất là nên xuất chúng trực tiếp. Trong phần này bạn bắt đầu tiến trình chuyển dữ liệu sang dạng thích hợp hơn thông qua các khuôn mẫu.

Sử dụng các khuôn mẫu

Mục đích căn bản là tạo một ứng dụng cho phép người dùng có quyền lựa chọn về nội dung cần hiển thị. Vì thế, việc bạn cần làm là tạo một hệ thống yêu cầu lập trình thay đổi sự xuất hiện của dữ liệu. Để giải quyết vấn đề này bạn có thể tạo ra các khuôn mẫu để chèn các dữ liệu động vào đó.

Ví dụ ban có thể tạo một khuôn mẫu như khuôn mẫu trong ví dụ 10.

Ví dụ 10. Khuôn mẫu
            <p><b><value/></b>:
          <value/></p>

Khuôn mẫu này có hai giá trị mà bạn có thể thay thế bằng dữ liệu động. Ví dụ 11 sẽ chỉ rõ hai cách dùng khác nhau của khuôn mẫu đơn giản này.

Ví dụ 11. Hai cách dùng khác nhau một khuôn mẫu

Nhấp vào để xem mã nguồn

Ví dụ 11. Hai cách dùng khác nhau một khuôn mẫu

<p><b>The West Wing</b>: When a
 uranium-bearing rig crashes in an Idaho tunnel, the White House scrambles 
to assess the potential crisis; election strategists mull dropping Vice
 President Hoynes (Tim Matheson) from the Democratic ticket.</p><p><b>One killed, one missing in Ohio storms; rare twister
 in New York state</b>: (Undated-AP) July 13, 2006 - At least
 one person died after up to nine inches of rain brought flooding to Indiana
 and Ohio, while tornado north of New York City partly collapsed a commercial
 building and ripped the roof off a hotel.</p>

Ở trường hợp thứ nhất, đây là dữ liệu của TV, và ở trường hợp hai là các kết quả tìm kiếm. Sự khác nhau giữa chúng là nguồn gốc tài liệu và biểu thức XPath đại diện cho những thứ được bổ sung. Ở trường hợp thứ nhất đó là /tv/programme/title/tv/programme/desc lấy giá trị từ XML. Trường hợp thứ hai là /ResultSet/Result/Title/ResultSet/Result/Summary lấy giá trị từ kết quả tìm kiếm trên Yahoo!. Trong phần này, bạn sẽ xem xét việc sử dụng XPath để chèn dữ liệu vào một khuôn mẫu và sau đó xuất kết quả dữ liệu.

Tạo văn bản khuôn mẫu

Bắt đầu, tạo một đối tượng Document ngoài khuôn mẫu, như bạn thấy ở ví dụ 12

Ví dụ 12. Tạo văn bản khuôn mẫu
...
         Document hostDoc = builder.parse(
              new InputSource(new StringReader("<div />")));
         Node hostRoot = hostDoc.getDocumentElement();
         
         for (int i=0; i < recordNodes.getLength(); i++) {
            
            String template =
 "<p><b><value/></b>:<value/></p>";
            Document templateDoc = builder.parse(
                   new InputSource(new StringReader(template)));
            
            
         }

         DOMSource source = new DOMSource(hostDoc);
         StreamResult result = new StreamResult(System.out);
...

Ở đây bạn áp dụng kỹ thuật mà bạn đã dùng để tạo văn bản gốc. Nhưng thay vì một phần tử đơn thì bạn xây dựng văn bản với khuôn mẫu thực mà bạn muốn sử dụng cho mỗi bản ghi trong các kết quả.

Tìm các nút để thay thế

Bước tiếp theo là dùng một biểu thức XPath để định vị tất cả các nút trong văn bản khuôn mẫu mà tất cả các khuôn mẫu đều gọi là giá trị như bạn thấy trong ví dụ 13.

Ví dụ 13. Tìm các nút để thay thế
                ...
         for (int i=0; i < recordNodes.getLength(); i++) {
            
            String template =
 "<p><b><value/></b>:<value/></p>";
            Document templateDoc = builder.parse(
                    new InputSource(new StringReader(template)));
            
            expression = "//value";
            NodeList templateNodes = 
                (NodeList) xpath.evaluate(
                   expression, templateDoc, XPathConstants.NODESET);
            for (int j=0; j < templateNodes.getLength(); j++){
               
              
            }
            
         }

         DOMSource source = new DOMSource(hostDoc);
...

Biểu thức XPath đại diện cho tất cả các phần tử giá trị trong Document, vì thế khi bạn đánh giá so sánh nó với đối tượng templateDoc, bạn lấy một NodeList nhằm vào tất cả các giá trị element trong Document đó. Sau đó bạn có thể lặp đi lặp lại từng Nodes và tiến hành việc thay thế.

Tìm dữ liệu thay thế

Hoạt động mà bạn muốn tiến hành là thay thế những phần tử đó bằng các dữ liệu cụ thể, vì thế bước tiếp theo là tìm các dữ liệu thay thế. Ở ví dụ 14 bạn sẽ tìm dữ liệu bằng cách sử dụng biểu thức XPath.

Ví dụ 14. Tìm dữ liệu thay thế
...
         for (int i=0; i < recordNodes.getLength(); i++) {
            
            String template =
 "<p><b><value/></b>:<value/></p>";
            Document templateDoc = builder.parse(
                   new InputSource(new StringReader(template)));
            
            String[] elementValues = {"title[@lang='en']", 
                                      "desc[@lang='en']"};
            
            expression = "//value";
            NodeList templateNodes = 
                (NodeList) xpath.evaluate(
                   expression, templateDoc, XPathConstants.NODESET);
            for (int j=0; j < templateNodes.getLength(); j++){
               
              
               if ( (Boolean)xpath.evaluate(elementValues[j], 
                                            recordNodes.item(i),
                                        XPathConstants.BOOLEAN)) {
   
                  Node valueNode =(Node)xpath.evaluate(
                                                  elementValues[j], 
                                               recordNodes.item(i),  
                                              XPathConstants.NODE);

                  String replacementValue = valueNode.getTextContent();

               }

            }
            
         }

         DOMSource source = new DOMSource(hostDoc);
...

Bạn có hai thông tin cấn thêm vào trong khuôn mẫu vì thế bạn cần định nghĩa hai biểu thức XPath khác nhau để điền vào. Đối với mỗi nút ghi, đầu tiên bạn kiểm tra xem liệu nút ghi (recordNodes.item(i)) chứa biểu thức đích không (elementValues[j]). (nút nội dung là /tv/programme, vì thế biểu thức XPath có liên quan đến nó.)

Nếu nút tồn tại thì bạn dùng phương thức evaluate() cùng với hằng số XPathConstants.NODE để truy lục nút. Bạn có thể trích văn bản thực của Node vì thế bạn sẽ bổ sung nó vào khuôn mẫu.

Bổ sung các thay thế vào khuôn mẫu

Bây giờ bạn đã có văn bản thay thế, bạn có thể bổ sung nó vào khuôn mẫu như trong ví dụ 15.

Ví dụ 15. Bổ sung các giá trị thay thế vào khuôn mẫu
...
            expression = "//value";
            NodeList templateNodes = (NodeList) xpath.evaluate(
                expression, templateDoc, XPathConstants.NODESET);
            for (int j=0; j < templateNodes.getLength(); j++){
               
               Node thisTemplateNode = templateNodes.item(j);
               Node parentNode = thisTemplateNode.getParentNode();
               
               if ( (Boolean)xpath.evaluate(elementValues[j], 
                   recordNodes.item(i), XPathConstants.BOOLEAN)) {
   
                  Node valueNode = (Node)xpath.evaluate(
                           elementValues[j], recordNodes.item(i), 
                           XPathConstants.NODE);
                  String replacementValue = valueNode.getTextContent();

                  Node replacementNode = 
                          templateDoc.createTextNode(replacementValue);
                  parentNode.replaceChild(replacementNode, 
                                          thisTemplateNode);

               }

            }
            
...

Đối với mỗi nút khuôn mẫu cần thay thế, đầu tiên lấy một tham chiếu cho nút cụ thể đó. Sau đó lấy một tham chiếu cho nút chính, nút này sẽ cho phép bạn thay thế nút khuôn mẫu.

Khi bạn đã xác định được rằng một giá trị thay thế tồn tại và truy vấn giá trị đó, trước tiên bạn tạo một nút văn bản trong templateDoc. Nút đó chứa giá trị thay thế. Sau đó bạn có thể dùng phương thức replaceChild() để thay thế phần tử giá trị gốc (thisTemplateNode) với nút văn bản thay thế mới. Kết quả là một khuôn mẫu có chứa thông tin mới

Bổ sung khuôn mẫu mới cho văn bản xuất

Khi bạn có khuôn mẫu hoàn chỉnh, bổ sung nó vào văn bản xuất theo cách bạn bổ sung dữ liệu thô trong phần trước, như ví dụ 16 dưới đây.

Ví dụ 16. Bổ sung khuôn mẫu hoàn chỉnh cho văn bản xuất
...
            for (int j=0; j < templateNodes.getLength(); j++){
...
                  parentNode.replaceChild(replacementNode, 
                                          thisTemplateNode);

               }

            }
            Node importedNode = hostDoc.importNode(
                      templateDoc.getDocumentElement(), true);
            hostRoot.appendChild(importedNode);
            hostRoot.appendChild(hostDoc.createTextNode("\n"));
            
         }

         DOMSource source = new DOMSource(hostDoc);
         StreamResult result = new StreamResult(System.out);
...

Đối với mỗi bản ghi, xử lý khuôn mẫu và bổ sung nó vào văn bản gốc như cách bạn đã bổ sung dữ liệu thô. Khi việc xử lý hoàn thành, xuất văn bản gốc như bình thường. Đối với văn bản danh sách tóm lược của TV kết quả sẽ như ví dụ 17.

Ví dụ 17. Kết quả cuối cùng
<?xml version="1.0"
 encoding="UTF-8"?><div><p><b>Flintstones</b>
:Fred gets fired and enters the pie-baking business.</p>
<p><b>Dastardly &amp; Muttley</b>:<value/></p>
<p><b>Banana Splits</b>:<value/></p>
<p><b>Project Runway</b>:<value/></p>
<p><b>Project Runway</b>:<value/></p>
<p><b>Celebrity Poker Showdown</b>:Angie Dickinson, Penn
 Jillette, Jeff Gordon, Kathy Griffin and Ron Livingston compete on behalf 
of their favorite charities.</p>
<p><b>Celebrity Poker Showdown</b>:Willie Garson, Jennie
 Garth, Richard Kind, Dave Navarro and Jerry O'Connell compete on behalf of
 their favorite charities.</p>
<p><b>Kathy Griffin: My Life on the D-List</b>:Kathy's 
trip to entertain the troops is winding down.</p>
<p><b>Kathy Griffin: My Life on the D-List</b>:Kathy has
 problems with her new puppy; the Learning Annex hires Kathy to teach a
 class.</p>
<p><b>Project Runway</b>:<value/></p>
<p><b>Project Runway</b>:<value/></p>
<p><b>The West Wing</b>:When a uranium-bearing rig 
crashes in an Idaho tunnel, the White House scrambles to assess the 
potential crisis; election strategists mull dropping Vice President 
Hoynes (Tim Matheson) from the Democratic ticket.</p>
</div>

Lưu ý rằng khuôn mẫu vẫn còn lưu phần tử giá trị trong trường hợp các dữ liệu không được tìm thấy trong văn bản nguồn. Trình duyệt sẽ lờ chúng đi nhưng bạn cũng sẽ phải có lựa chọn để đưa chúng vào trong các không gian tên riêng biệt hoặc thậm chí loại bỏ chúng hẳn trước khi xuất. (Ví dụ, đó có thể là một ứng dụng tốt cho việc chuyển đổi XSL)


Đồng nhất hơn: Nhiều loại dịch vụ

Ở đây bạn có thể kiểm soát dữ liệu xuất của ứng dụng thông qua một loạt chuỗi ký tự, kiểm soát được dữ liệu chúng đại diện cho khuôn mẫu hay biểu thức XPath để điền vào khuôn mẫu. Trong phần này bạn sẽ khái quát ứng dụng kỹ hơn, cho phép bạn bổ sung các dịch vụ một cách tự động và loại bỏ các dịch vụ khỏi đầu xuất bằng cách kiểm soát nội dung của một mảng.

Tạo mảng các dịch vụ

Bước đầu tiên là tạo một mảng của các đối tượng Service có chứa đựng các thông tin cần thiết để xử lý chúng. Trong ứng dụng cuối cùng bạn sẽ tạo ma trận này một cách linh hoạt, có thể bằng cách kéo thông tin dịch vụ từ một cơ sở dữ liệu. Nhưng bây giờ bạn cần tạo một lớp Service và các thành viên của nó như trong ví dụ 18.

Ví dụ 18. Tạo mảng dịch vụ
public class Service {

   String name = "";
   String baseURL = "";
   String template = "";
   String[] elementValues = {"title", "desc"};
   String recordExp = ""; 
      
   public static Service[] getServices(){
      Service[] services = new Service[2];

      Service thisService = new Service();
      
      thisService.name = "Yahoo! Search";
      thisService.baseURL = 
"http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid=ma
shupid&type=all&query=New+York";
      thisService.template =
 "<p><b><value/></b>:<value/></p>";
      thisService.elementValues[0] = "Title";
      thisService.elementValues[1] = "Summary";
      thisService.recordExp = "/ResultSet/Result";
      services[0] = thisService;

      Service thisService2 = new Service();
      
      thisService2.name = "YouTube";
      thisService2.baseURL = 
"http://www.youtube.com/api2_rest?method=youtube.videos.list_by_tag&d
ev_id=s2gNEM-7qoU&tag=New+York";
      thisService2.template =
 "<p><value/>:<value/></p>";
      thisService2.elementValues[0] = "title";
      thisService2.elementValues[1] = "description";
      thisService2.recordExp = "/ut_response/video_list/video";
      services[1] = thisService2;

      return services;
      
   }
}

Đây không phải là một tuyệt phẩm của Java nhưng nó thực hiện những gì cần thực hiện. Nó tạo ra một lớp bao gồm các giá trị thuộc tính mà bạn đã mã hóa vào trong ứng dụng, ví dụ như khuôn mẫu và biểu thức XPath đại diện một bản ghi riêng lẻ. Nó cũng bao gồm các thuộc tính rất riêng biệt đối với mỗi dịch vụ như là URL và tên.

Lớp bao gồm một phương thức tĩnh, getServices(), tạo ra hai đối tượng Service và bổ sung chúng vào một mảng.

Bạn sẽ sử dụng mảng đó trong ứng dụng của mình.

Lặp đi lặp lại các dịch vụ

Bổ sung từng dịch vụ tương đối dễ dàng, bạn có thể thấy trong ví dụ 19.

Ví dụ 19. Bổ sung nhiều loại dịch vụ
...
public class SimpleClient {
   
   public static void main(String[] args) {

      try {

         Service[] svcs = Service.getServices();
         DocumentBuilder builder =    
          DocumentBuilderFactory.newInstance().newDocumentBuilder();

         Document hostDoc = builder.parse(
                      new InputSource(new StringReader("<div />")));
         Node hostRoot = hostDoc.getDocumentElement();         
         
         for (int s=0; s < svcs.length; s++){
   
            Service svc = svcs[s];
            Document document = builder.parse(svc.baseURL);
      
            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression = svc.recordExp;
            NodeList recordNodes = (NodeList) xpath.evaluate(
                    expression, document, XPathConstants.NODESET);
            
            Node titleNode = hostDoc.createTextNode(svc.name);
            Element titleElement = hostDoc.createElement("h1");
            titleElement.appendChild(titleNode);
            
            hostRoot.appendChild(titleElement);
            
            for (int i=0; i < recordNodes.getLength(); i++) {
            
               String template = svc.template;
               Document templateDoc = builder.parse(
                   new InputSource(new StringReader(template)));
            
               String[] elementValues = svc.elementValues;
            
               expression = "//value";
               NodeList templateNodes = (NodeList) xpath.evaluate(
                                                     expression, 
                                                    templateDoc, 
                                         XPathConstants.NODESET);
               for (int j=0; j < templateNodes.getLength(); j++){
               
                  Node thisTemplateNode = templateNodes.item(j);
                  Node parentNode = thisTemplateNode.getParentNode();
               
                  if ( (Boolean)xpath.evaluate(elementValues[j], 
                                            recordNodes.item(i), 
                                         XPathConstants.BOOLEAN)) {
   
                     Node valueNode = (Node)xpath.evaluate(
                                                elementValues[j],  
                                             recordNodes.item(i), 
                                            XPathConstants.NODE);
                     String replacementValue = 
                                      valueNode.getTextContent();
                     Node replacementNode = 
                       templateDoc.createTextNode(replacementValue);
                     parentNode.replaceChild(replacementNode, 
                                             thisTemplateNode);

                  }

               }
               Node importedNode = hostDoc.importNode(
                          templateDoc.getDocumentElement(), true);
               hostRoot.appendChild(importedNode);
               hostRoot.appendChild(hostDoc.createTextNode("\n"));
            
            }

         }   
            
         DOMSource source = new DOMSource(hostDoc);
         StreamResult result = new StreamResult(System.out);
         TransformerFactory transFactory = 
                           TransformerFactory.newInstance();
         Transformer transformer = transFactory.newTransformer();
         transformer.transform(source, result);   
         
      } catch (Exception e){
      
         e.printStackTrace();
      }
   }
}

Trước tiên lấy mảng của các dịch vụ. Sau đó lặp đi lặp lại các mảng và xử lý các dịch vụ như cách bạn xử lý trước đây, lấy các giá trị từ đối tượng Service thay thế giá trị được gán khi viết mã (hard-coded) đã được dùng trước đây. Đoạn mã cũng bổ sung một tiêu đề bằng tên của từng dịch vụ trên văn bản xuất.

Kết quả là một văn bản bao gồm tất cả các dữ liệu xuất của cả hai dịch vụ như trong ví dụ 20.

Ví dụ 20. Dữ liệu xuất của cả hai dịch vụ
<?xml version="1.0" encoding="UTF-8"?><div><h1>Yahoo!
 Search</h1><p>
<b>Severe Weather Hits Ohio, New York</b>:Severe
 weather hit New York 
and the Ohio region. Up to 9 inches of rain brought flooding to 
Indiana and Ohio on Wednesday, killing a woman. North of New York 
City, a tornado partly collapsed a commercial building and ripped the 
roof off a hotel.</p>
<p><b>Musei: a New York ticket di 20 dlr</b>:(ANSA) - 
NEW YORK, 13 LUG 
- Il Metropolitan Museum di New York ha alzato il prezzo suggerito per 
l'ingresso di un adulto da 15 a 20 dollari.</p>
<p><b>One killed, one missing in Ohio storms; rare twister in 
New York ...
Europe through Vodafone Group in hopes of resolving technical problems 
with a previous model</p>
<h1>YouTube</h1><p>New York Dolls-Jet Boy live:NEW
 YORK DOLLS =D YAY</p>
<p>Rolling Stones-Dead Flowers live:Rolling stones perform dead 
...
<p>maurice:New york</p>
</div>

Ví dụ trên tương đối lộn xộn nhưng các chi tiết thì hết sức thú vị bao gồm element div (phần tử div) chính, tên các loại dịch vụ, và thực tế là mỗi dịch vụ có một khuôn mẫu khác nhau.


Đưa ứng dụng lên Web

Đến đây ứng dụng đã hoàn thành nhưng nó vẫn cần được chuyển lên Web. Để chuyển nó lên Web bạn cần bổ sung mã cho servlet. Servlet có hai phương thức chính: doGet()doPost(). Khi trình duyệt yêu cầu servlet sử dụng phương thức GET, nó hiển thị một dạng thức đơn giản cho phép người dùng nhập một truy vấn. Khi người dùng chấp nhận dạng truy vấn, nó đưa truy vấn đến phương thức POST, và servlet xử lý dữ liệu như trước đây

Tạo servlet

Đầy tiên tạo một servlet thực như ở ví dụ 21.

Ví dụ 21. Tạo một servlet thực
import java.io.IOException; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse;
          
     public class MashupClientServlet 
            extends javax.servlet.http.HttpServlet 
            implements javax.servlet.Servlet { 
            
       public MashupClientServlet() { 
            super(); 
       } 
       
       protected void doGet(HttpServletRequest request, 
                HttpServletResponse response) 
                    throws ServletException, IOException { 
        response.getWriter().print("<html>");
        response.getWriter().print("<head></head>");
        response.getWriter().print("<body>");
        
        response.getWriter().print("<h1>The Mashup</h1>");
        response.getWriter().print("<p>Enter a keyword:</p>");
        response.getWriter().print( 
            "<form action='MashupClientServlet' method='post'>"); 
        response.getWriter().print( 
                    "<input type='text' name='query' />"); 
        response.getWriter().print("<input type='submit'/>"); 
        response.getWriter().print("</form>");
        response.getWriter().print("</body>");
        response.getWriter().print("</html>"); 
        } 
        
        protected void doPost(HttpServletRequest request, 
                    HttpServletResponse response) 
                    throws ServletException, IOException {
       // Actual processing goes here 
       
      } 
   }

Đây là một servlet chuẩn. Nếu bạn lưu nó và triển khai nó tới máy chủ của bạn thì sau đó gọi nó từ trình duyệt, bạn sẽ thấy những thứ tương tự trong hình 1.

Hình 1. Phương thức doGet()
Phương thức doget()

Điều chỉnh thông tin Service

Vì bạn lấy từ khóa từ biểu mẫu, bạn cần tạo ra một thay đổi nhỏ sao cho khóa không còn bị nhúng trong URL đại diện cho yêu cầu REST như trong ví dụ 22.

Ví dụ 22. Điều chỉnh thông tin Service
...
      thisService.name = "Yahoo! News Search";
      thisService.baseURL = 
"http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid=ma
shupid&type=all&query=";
      thisService.template =
 "<p><b><value/></b>:<value/></p>";
...
      thisService2.name = "YouTube";
      thisService2.baseURL = 
"http://www.youtube.com/api2_rest?method=youtube.videos.list_by_tag&de
v_id=s2gNEM-7qoU&tag=";
      thisService2.template =
 "<p><value/>:<value/></p>";
...

Nếu bạn không làm thế thì thông tin sẽ không bị thay đổi. Bạn sẽ phải thêm các khóa trở lại trước khi bạn gọi dịch vụ.

Servlet hoàn chỉnh

Hoàn chỉnh một servlet là vấn đề dễ dàng của việc chuyển đổi các chức năng mà bạn vừa xây dựng cho phương thức doPost(), như bạn thấy trong ví dụ 23.

Ví dụ 23. Servlet hoàn chỉnh
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import java.io.IOException;
import java.io.StringReader;
 
 public class MashupClientServlet extends javax.servlet.http.HttpServlet
 implements javax.servlet.Servlet {

   public MashupClientServlet() {
      super();
   }      
   

   protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) 
                        throws ServletException, IOException {
      response.getWriter().print("<html>");
...
      response.getWriter().print("</html>");
   }     
   
   protected void doPost(HttpServletRequest request, 
                         HttpServletResponse response) 
                              throws ServletException, IOException {
      try {

         String query = request.getParameter("query").toString();
         
         Service[] svcs = Service.getServices();
         DocumentBuilder builder = 
           DocumentBuilderFactory.newInstance().newDocumentBuilder();

         Document hostDoc = builder.parse(
                   new InputSource(new StringReader("<div />")));
         Node hostRoot = hostDoc.getDocumentElement();         
         
         for (int s=0; s < svcs.length; s++){
   
            Service svc = svcs[s];
            Document document = builder.parse(svc.baseURL+query);
      
            XPath xpath = XPathFactory.newInstance().newXPath();
...

         }   
            
         DOMSource source = new DOMSource(hostDoc);
         StreamResult result = new StreamResult(response.getWriter());
         TransformerFactory transFactory = 
                           TransformerFactory.newInstance();
         Transformer transformer = transFactory.newTransformer();
         transformer.transform(source, result);   
         
      } catch (Exception e){
      
         e.printStackTrace();
      }

   }               
}

Tất cả những gì bạn làm ở đây là lấy nội dung của phương thức main() của lớp Standalone và bổ sung nó vào nội dung của phương thức doPost(), với ba thay đổi nhỏ. Đầu tiên bạn truy lục truy vấn do người dùng nhập và sau đó bạn bổ sung truy vấn tới đoạn cuối của URLs để được yêu cầu.

Cuối cùng, bạn không xuất kết quả tới dòng lệnh mà xuất nó tới trang Web.

Kết quả sẽ trông như hình 2.

Hình 2. Kết quả chạy servlet
Kết quả chạy servlet

Thêm khuôn mẫu thuộc tính

Nếu bạn cuộn xuống dưới trang bạn sẽ thấy rằng kết quả của YouTube vẫn nằm trên trang đó, nhưng trông chúng không đẹp bởi vì chúng không có hình ảnh. Tương tự, mọi thứ trông sẽ hay hơn nếu có thể cung cấp đường liên kết tới các mục mới do Yahoo! trình bày. Để làm được điều đó bạn cần cung cấp một cách cố định các thuộc tính trong các khuôn mẫu của bạn, và không chỉ các phần tử mà thôi.

Để thực hiện bạn cần bổ sung một thuộc tính mới tới lớp Service, và sửa đổi các khuôn mẫu một chút như trong ví dụ 24.

Ví dụ 24. Bổ sung các thuộc tính tới lớp dùng chung Service
public class Service {

   String name = "";
   String baseURL = "";
   String template = "";
   String[] elementValues = {"title", 
                       "desc"};
   String[] attributeValues = {"src"};
   String recordExp = ""; 


public static Service[] getServices(){
      Service[] services = new Service[2];
          
      Service thisService = new Service();
      thisService.name = "Yahoo! Search";
      thisService.baseURL = 
"http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid=ma
shupid&type=all&query=";
      thisService.template = 
           "<p><b><a
 value='href'><value/></a></b>:<value/>
</p>";
      thisService.elementValues[0] = "Title";
      thisService.elementValues[1] = "Summary";
      thisService.attributeValues[0] = "ClickUrl";
      thisService.recordExp = "/ResultSet/Result";   
      services[0] = thisService;

      Service thisService2 = new Service();
      thisService2.name = "YouTube";
      thisService2.baseURL = 
"http://www.youtube.com/api2_rest?method=youtube.videos.list_by_tag&de
v_id=s2gNEM-7qoU&tag=";
      thisService2.template = 
                  "<p><img value='src' />
 <value/>:<value/></p>";
      thisService2.elementValues[0] = "title";
      thisService2.elementValues[1] = "description";
      thisService2.attributeValues[0] = "thumbnail_url";
      thisService2.recordExp = "/ut_response/video_list/video";
      services[1] = thisService2;
      
      return services;
      
   }
}

Ở đây bạn bổ sung một mảng attributeValues (giá trị- thuộc tính) cho mỗi đối tượng, nhưng bạn cũng bổ sung các thuộc tính mới cho các khuôn mẫu. Dạng này hơi khác một chút so với các phần tử giá trị. Thuộc tính giá trị chỉ định phần tử mang thuộc tính và tên của thuộc tính xuất hiện trên văn bản cuối cùng. Ví dụ, phần tử khuôn mẫu <img value='src' /> được dịch sang phần tử của <img src="(contents of the thumbnail_url)" />.

Hãy xem cách chúng thực hiện

Xử lý các khuôn mẫu thuộc tính

Xử lý các khuôn mẫu thuộc tính tương tự cách xử lý các giá trị phần tử như bạn nhìn thấy trong ví dụ 25.

Ví dụ 25. Xử lý các khuôn mẫu thuộc tính
...
                     String replacementValue = 
                                 valueNode.getTextContent();
                     Node replacementNode = 
                      templateDoc.createTextNode(replacementValue);
                     parentNode.replaceChild(replacementNode, 
                                             thisTemplateNode);

                  }
               }

               expression = "//@value";
               templateNodes = (NodeList) xpath.evaluate(
                   expression, templateDoc, XPathConstants.NODESET);
               for (int j=0; j < templateNodes.getLength(); j++){
            
                  Attr thisNode = (Attr) templateNodes.item(j);
                  Element parentElement =  
                                 (Element)thisNode.getOwnerElement();
                    parentElement.removeAttribute("value");
                  if ( (Boolean)xpath.evaluate(svc.attributeValues[j], 
                                               recordNodes.item(i), 
                                             XPathConstants.BOOLEAN)) {
                     Node valueNode = (Node)xpath.evaluate(
                                               svc.attributeValues[j],  
                                               recordNodes.item(i), 
                                               XPathConstants.NODE);
                     parentElement.setAttribute(
                                            thisNode.getNodeValue(), 
                                         valueNode.getTextContent());   

                  } 
               }
               
               Node importedNode = hostDoc.importNode(
                         templateDoc.getDocumentElement(), true);
               hostRoot.appendChild(importedNode);
               hostRoot.appendChild(hostDoc.createTextNode("\n"));
            
            }
         }   
...

Đầu tiên định nghĩa biểu thức XPath cho các thuộc tính được gọi là giá trị và lập danh sách các nút (Nodes) mà thuộc tính áp dụng. Đối với từng thuộc tính, lấy tham chiếu tới Node, và sau đó gán vào phần tử. Khi bạn làm được điều này bạn có thể loại bỏ thuộc tính cũ và nếu các thông tin tương đương vẫn còn thì bạn bổ sung thông tin mới với giá trị thay thế.

Đáp lại sẽ là một trang bao gồm các đường liên kết và hình ảnh, như bạn có thể thấy ở hình 3.

Hình 3. Các liên kết và hình ảnh
Các liên kết và hình ảnh

Trộn các dịch vụ lại với nhau

Cho đến bây giờ, bạn đã có thể tạo ra một Mashup khi bạn có thông tin từ những dịch vụ khác nhau, nhưng sự thật là chúng cũng không thể tương tác với các thành phần khác. Trong phần này, bạn có thể thay đổi điều đó. Bạn có thể thêm vào dịch vụ thứ ba các truy vấn kiểu Technorati để đưa ra số thời gian các blogger có liên kết đến URL và hiển thị các giá trị của các cổng vào được trả bởi dịch vụ của Yahoo.

Tách rời tiến trình thành một phương thức riêng biệt

Bước đầu tiên là lấy một tiến trình của một dịch vụ ra khỏi phương thức doPost() và đưa nó vào phương thức của chính nó bởi vậy bạn có thế gọi nó một cách đệ quy, như ví dụ 26

Ví dụ 26. Tách rời tiến trình thành một phương thức riêng biệt
...
public class MashupClientServlet 
          extends javax.servlet.http.HttpServlet 
                         implements javax.servlet.Servlet {

   public MashupClientServlet() {
      super();
   }      
   

   protected void doGet(HttpServletRequest request, 
                        HttpServletResponse response) 
                        throws ServletException, IOException {
...
   }     
   
   public static Node renderService(String query, Service svc, 
                                    Document hostDoc){

      try {
         Node serviceElement = hostDoc.createElement("span");
         DocumentBuilder builder =  
          DocumentBuilderFactory.newInstance().newDocumentBuilder();
         Document document = builder.parse(svc.baseURL+query);

   ...
         
         toImport = hostDoc.importNode(templateDoc.getDocumentElement(),
 true);
         serviceElement.appendChild(toImport);
      }

      
         return serviceElement;
      } catch (Exception e){
         e.printStackTrace();
         return null;
      }
   }

   protected void doPost(HttpServletRequest request, 
                         HttpServletResponse response) 
                     throws ServletException, IOException {

      String query = request.getParameter("query").toString();
      
      try {
         DocumentBuilder builder = 
           DocumentBuilderFactory.newInstance().newDocumentBuilder();
   
      
         Service[] svcs = Service.getServices();
         Document hostDoc = builder.parse(
             new InputSource(new StringReader("<div/>")));
         Node hostRoot = hostDoc.getDocumentElement();
    
         for (int k=0; k < svcs.length; k++){
      
            
            Service svc = svcs[k];

            Element nameElement = hostDoc.createElement("h1");
            nameElement.appendChild(hostDoc.createTextNode(svc.name));

            Node serviceElement = hostDoc.createElement("span");
            serviceElement.appendChild(nameElement);

            serviceElement.appendChild(
                        renderService(query, svc, hostDoc));

            hostRoot.appendChild(serviceElement);
            hostRoot.appendChild(hostDoc.createTextNode("\n"));

         
         }            

         DOMSource source = new DOMSource(hostDoc);
...

Đầu tiên, phải tạo ra một phương thức mới renderService(), rồi đưa ra truy vấn cho đối tượng Service và Document, bởi vậy bạn có thể sao chép rồi dán hàm này vào phương thức mà không cần thay đổi bất kỳ tham số nào. Phương thức sẽ trả về serviceElement, hoặc một tập hợp của tất cả các tiến trình mẫu cho dịch vụ này. Bởi vì nó là một phần của tài liệu đầu ra, bạn có thể dễ dàng thêm vào tài liệu các kết quả như cách thông thường bạn vẫn làm.

Nếu bạn lưu lại và chạy thử servlet, bạn có thể nhìn thấy kết quả giống hệt như lần trước (mặc dù bản thân kết quả có thể khác, hiển nhiên!) bởi vì bạn không thể thay đổi bất kỳ một chức năng nào chỉ có thay đổi vị trí của chúng rất ít.

Thêm các dịch vụ con (subservices)

Để có thể thêm các dịch vụ con (subservice), bạn sẽ phải tạo ra vài sự thay đổi trong lớp Service, xem trong ví dụ 27.

Listing 27. Tạo các dịch vụ con
public class Service {

   String name = "";
   String baseURL = "";
   String template = "";
   String[] elementValues = {"title", 
                             "desc"};
   String[] attributeValues = {"src"};
   String recordExp = ""; 
   Service subSvc = null;
   String filterExp = ""; 
   
   public static Service[] getServices(){
       Service[] services = new Service[2];

       Service subService = new Service();
            
       subService.name = "Technorati";
       subService.baseURL =
 "http://api.technorati.com/cosmos?key=0368d22f6a2f864dad1c59feb07153ee
&url=";
      subService.template = "<span><value/></span>";
      subService.elementValues[0] = "inboundlinks";
      subService.elementValues[1] = "bogus";
      subService.attributeValues[0] = "thumbnail_url";
      subService.recordExp = "/tapi/document/result";

      Service thisService = new Service();
      
      thisService.name = "Yahoo! Search";
      thisService.baseURL =
 "http://api.search.yahoo.com/NewsSearchService/V1/newsSearch?appid=ma
shupid&type=all&query=";
      thisService.template = "<p><b><a
 value='href'><value/></a></b>"
               + ":<value/> (Linked <subService/>
 times)</p>";
      thisService.elementValues[0] = "Title";
      thisService.elementValues[1] = "Summary";
      thisService.attributeValues[0] = "ClickUrl";
      
      thisService.recordExp = "/ResultSet/Result";
      
      thisService.subSvc = subService;
      thisService.filterExp = "ClickUrl";
   
      services[0] = thisService;

...

Để bắt đầu, hãy sửa đổi lớp Service cho phép đối tượng subservice trông giống như một biểu thức dùng để lọc các dịch vụ con.

Từ ví dụ, bạn định nghĩa một đối tượng Service cho dịch vụ Technorati, một thành phần giống như dịch vụ con dành cho dịch vụ Yahoo!. Để gọi được dịch vụ Technorati, bạn cần kiểm tra URL đã được đánh dấu hay chưa. URL đóng vai trò như một biểu thức lọc, chương trình lọc sẽ trả về kết quả dựa trên URL. Nếu bạn nhìn thấy nơi mà bạn thêm các dịch vụ con vào dịch vụ Yahoo!, bạn sẽ thấy rằng bạn đã chỉ rõ cho URL nơi bạn sẽ thực hiện lọc dịch vụ Technorati bằng cách sử dụng giá trị ClickUrl của dịch vụ Yahoo!.

Tuy nhiên cũng phải chú ý trong ví dụ 27 để thêm một phần tử subService vào khuôn mẫu của dịch vụ Yahoo!, cần phải chỉ ra ứng dụng chứa đựng cả đầu ra của dịch vụ con.

Cách làm này còn hơn là bạn gọi trực tiếp đến dịch vụ và thực tế thì dịch vụ này không cần được thêm vào mảng.

Xử lý các dịch vụ con

Tiến trình subservice là một phần của quá trình gọi đệ quy phương thức renderService() giống như bạn nhìn thấy trong ví dụ 28

Ví dụ 28. Xử lý các dịch vụ con
...
   public static Node renderService(String query, Service svc, 
                                    Document hostDoc){

      try {
...
            parentElement.removeAttribute("value");
            if ( (Boolean)xpath.evaluate(svc.attributeValues[j],
 recordNodes.item(i), XPathConstants.BOOLEAN)) {
               Node valueNode = (Node)xpath.evaluate(svc.attributeValues[j],
 recordNodes.item(i), XPathConstants.NODE);
               parentElement.setAttribute(thisNode.getNodeValue(),
 valueNode.getTextContent());   

            } 
         }
         
         expression = "//subService";
         NodeList subServiceNodes = (NodeList) xpath.evaluate(
                expression, templateDoc, XPathConstants.NODESET);
         if (subServiceNodes.getLength() > 0) {
            Node thisNode = subServiceNodes.item(0);            
            Node parentNode = thisNode.getParentNode();
            if ( (Boolean)xpath.evaluate(svc.filterExp, 
                    recordNodes.item(i), XPathConstants.BOOLEAN)) {
               Node valueNode = (Node)xpath.evaluate(svc.filterExp, 
                          recordNodes.item(i), XPathConstants.NODE);
               String filter = valueNode.getTextContent();
               Node renderedSubService = 
                      renderService(filter, svc.subSvc, hostDoc);
               toImport = templateDoc.importNode(renderedSubService, 
                                                 true);
               parentNode.replaceChild(toImport, thisNode);
            }             
         }         
         
         toImport = hostDoc.importNode(templateDoc.getDocumentElement(),
 true);
         serviceElement.appendChild(toImport);
      }

      
      return serviceElement;
      } catch (Exception e){
         e.printStackTrace();
         return null;
      }
   }

...

Sau khi mã nguồn kiểm tra các mẫu cho các giá trị và thuộc tính của các phần tử, nó sẽ tìm kiếm phần tử subService. Tiến trình là một quá trình giống hệt nhau nhằm thay thế giá trị của các phần tử, ngoại trừ trường hợp chương trình ứng dụng tìm thấy phần từ subService, thậm chí tìm thấy dữ liệu từ một biểu thức XPath, nó sẽ đưa vào dịch vụ con và thực hiện lọc bằng phương thức renderService(), phương thức này thực hiện thay thế lặp đi lặp lại một hoặc nhiều nút bằng các phần tử subService.

Hình 4 là kết quả của quá trình thực hiện servlet và một vài kết quả được trả lại bởi các dịch vụ Yahoo!, xem chú thích để biết cách tạo liên kết đến Technorati và tìm kiếm cụm từ "boing boing".

Hình 4. Mashup cuối cùng
Mashup cuối cùng

Chú ý rằng sự thực thi không phải là vấn đề chính vì bạn không chỉ tạo ra hai, ba hay mười hai truy vấn Web khác nhau. Nhưng chúng ta sẽ đề cập đến sự thực thi thậm chí trong cả phần 2.


Tổng kết

Đại ý

Trong bài viết này, bạn sẽ biết cách sử dụng dữ liệu từ dịch vụ Web APIs cơ bản REST bằng cách dùng kỹ thuật XML giống như thao tác DOM và XPath. Bạn sẽ biết cách tạo ra một Mashup từ các dịch vụ khác nhau bằng cách chỉ ra một hoặc nhiều dịch vụ trên trang Web sau đó hợp nhất dịch vụ này với một dịch vụ khác. Bạn làm những điều này dựa trên các các mẫu gần đúng, những thứ cho phép bạn thêm vào các dịch vụ và thay đổi giao diện về sau.

Điều này sẽ có ích vào một lúc nào đó trong tương lai, khi mà chương trình của bạn tự động thêm và thay đổi các dịch vụ.

Trong phần 2, bạn sẽ tìm thấy cách làm thế nào để lưu trữ dữ liệu tự nhiên XML trong DB2 để tạo ra nguồn của khối bộ nhớ lưu trữ dữ liệu.


Tải về

Mô tảTênKích thước
Mã nguồn Phần 1x-ultimashup1/mashup1_source.zip8KB

Tài nguyên

Học tập

Lấy sản phẩm và công nghệ

Thảo luận

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Information Management, Công nghệ Java, Nguồn mở, SOA và dịch vụ Web
ArticleID=391000
ArticleTitle=Ultimate mashup – Các dịch vụ Web và Web ngữ nghĩa (semantic Web), Phần 6: Sử dụng kết hợp các dịch vụ Web
publish-date=03082007