Đề tài Các dịch vụ Web và Web ngữ nghĩa - Phần 5

Tóm tắt: Loạt bài viết này trình bày chi tiết việc tạo ra một ứng dụng Mashup cho phép kiểm soát các dữ liệu được hiển thị với người sử dụng. Bây giờ bạn biết làm thế nào để tạo một bản thể luận (ontology) để xác định khái niệm đại diện của một dịch vụ, bạn có thể cho phép người dùng lựa chọn dịch vụ mà họ muốn sử dụng

pdf92 trang | Chia sẻ: tlsuongmuoi | Lượt xem: 1910 | Lượt tải: 1download
Bạn đang xem trước 20 trang tài liệu Đề tài Các dịch vụ Web và Web ngữ nghĩa - Phần 5, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
g các biểu thức XPath trong các mảng elementValues và các giá trị thuộc tính attributeValues. Trong trường hợp này, bạn cũng có thể thấy phần gắn thêm của một dịch vụ thứ hai và được thể hiện bởi thành tố dịch vụ con subservice. Các bài viết trước: các tính năng tiên tiến Trong Phần 2, bạn phát triển phần ứng dụng hơn là tạo ra một yêu cầu Web cho tất các các yêu cầu dịch vụ - đây là một quá trình có thể kéo dài đến vài phút nếu phần mashup tạo ra nhiều yêu cầu - bạn bắt đầu lưu giữ các kết quả yêu cầu trong cơ sở dữ liệu XML có sử dụng khả năng pureXML mới của DB2. Điều này cho phép bạn kiểm tra một cơ sở dữ liệu cho một yêu cầu cụ thể trước khi chạy Mashup và tạo một cái mới. Nhưng mục tiêu tổng quát là tạo ra một dịch vụ thông minh – với nó người sử dụng có thể yêu cầu một kiểu dữ liệu cụ thể - như sách, giá...- và mashup sẽ hiểu làm thế nào để tìm được cho dù vấn đề không phải là bạn sử dụng dịch vụ nào. Để làm được điều này, ở Phần 3 và 4, bạn sẽ học cách tạo bản thể luận hoặc phân loại các khái niệm. Bằng cách này, bạn có thể định nghĩa các khái niệm như cuốn sách, giá cả,… để cung cấp một hình thức chung và sắp xếp từ đó bạn có thể xử lý từng kiểu dịch vụ chứ không phải chỉ là từng dịch vụ. Ở phần 4, bạn đã tạo ra một bản thể luận của hiệu sách có rất nhiều các khái niệm, định nghĩa mà bạn có thể tìm thấy trong các hiệu sách điện tử, như sách, DVD, cho rất nhiều khái niệm có thể được tìm kiếm từ các lưu trữ điện tử như sách, DVD, tác giả...ở phần hướng dẫn bạn có thể bắt đầu thêm vào các dữ liệu thực tế cho bản thể luận này. Bản thể luận cơ sở Bản thể luận cở sở trông tương tự như sau (xem ví dụ 2). Ví dụ 2. Bản thể luận cơ sở <!DOCTYPE rdf:RDF [ ]> <rdf:RDF xmlns = "" xmlns:store = "" xml:base = "" xmlns:owl = "" xmlns:rdf = "" xmlns:rdfs= "" xmlns:xsd = "" > An example OWL ontology for Online Bookstores (The Ultimate Mashup: Part #4) BookStore Ontology Web Service <owl:minCardinality rdf:datatype="&xsd;nonNegativeInteger">1 Online Store Bookstore Product sold at online store Book <owl:minCardinality rdf:datatype="&xsd;nonNegativeInteger">1 Movie Person Author <owl:minCardinality rdf:datatype="&xsd;nonNegativeInteger">1 Director Bạn sẽ không sử dụng tất cả các định nghĩa này trong phần hướng dẫn, nhưng điều quan trọng cần nhận biết là cấu trúc, một kho Store chứa StockItems có thể ví dụ là Book, Movie và vân vân. Theo cách này bạn có thể xác định một Book một cách khái quát, các thiết lập thuộc tính về tác giả, nhà xuất bản,…nhưng vẫn còn sự khác biệt về giá cả và thông tin giao hàng phụ thuộc vào các kho hàng mà từ đó khách hàng mua sách. Nhớ là chúng chỉ là các định nghĩa. Dữ liệu thực tế bao gồm các cá thể hoặc những ví dụ cho mỗi lớp. Ví dụ (xem ví dụ 3). Ví dụ 3. Các cá thể của bản thể luận ... <itemPrice rdf:datatype="" >29.99 Harry Potter and the Sorcerers Stone <stockedProduct rdf:resource="#Harry_Potter_and_the_Sorcerers_Stone" /> <bundledWith rdf:resource="#Harry_Potter_and_the_Sorcerers_Stone"/> ... Bạn có thể đặt những cá thể này trong tệp riêng của chúng hoặc trong cùng một tệp của các định nghĩa; điều quan trọng là các không gian tên phải phù hợp với nhau. Trong bài viết này, bạn sẽ tạo các cá thể từ dữ liệu chiết xuất được từ các dịch vụ Web cụ thể. Cài đặt Bài viết này giả định rằng bạn đã có một hệ thống mashup được cài đặt và đang làm việc, đồng thời có hoặc không có bộ nhớ cơ sở dữ liệu DB2. Để biết thêm thông tin về việc thiết lập Tomcat và các thành phần khác, xem Phần 1 và Phần 2 của loạt bài viết (xem Tài nguyên). Bạn cũng có thể cần đến Jena API để hoàn thành các đoạn mã trong bài viết này. Có thể tải Jena từ Để cài đặt, đơn giản chỉ cần thêm các tệp Jena *.jar vào đường dẫn lớp (class path). bài viết này sử dụng các dịch vụ giao diện của Amazon Web làm ví dụ. Để thực hiện việc mã hóa, bạn cần có các biểu tượng phát triển (developers token), và thay thế chuỗi các số 0 (000000000000000) trong mã bằng công cụ đó. Để có biểu tượng phát triển, xem ạo cho người sử dụng sự lựa chọn: giao diện Mục đích của bài viết này là cung cấp một phương thức cho người dùng thay thế một dịch vụ bằng một dịch vụ khác dựa trên thông tin trong bản thể luận. Hãy bắt đầu bằng việc cho người dùng một lựa chọn. Tạo ra các cá thể Bước đầu tiên là tạo một cá thể từ đó khách hàng sẽ lựa chọn. Bạn sẽ phải tạo ra các trường hợp cá biệt của các lớp Bookstore. Ví dụ, tệp bản thể luận hiện nay nhìn giống như ví dụ 4. Ví dụ 4. Tạo ra các cá thể <Book rdf:ID="Harry_Potter_and_the_Sorcerers_Stone"> <writtenBy rdf:resource="#J_K_Rowling"/> Nhưng tất nhiên chúng hiện chỉ đơn thuần là Bookstores. Sau đó, bạn phải thêm thuộc tính cho chúng Ghi nhớ là bạn có vài cá thể ở đây và có nhiều loại khác nhau. Bạn phải sử dụng API để kiểm tra các đối tượng này. Tạo ra mô hình Để trông gọn gàng hơn một chút, bạn sẽ phải điều chỉnh tất cả các chức năng bản thể luận ở trong một lớp mới, MashupOntologyReader. Bắt đầu bằng việc tạo ra lớp cơ bản (xem ví dụ 5): Ví dụ 5. Lớp cơ bản import com.hp.hpl.jena.ontology.*; import java.util.Iterator; import com.hp.hpl.jena.rdf.model.ModelFactory; public class MashupOntologyReader { private OntModel bookStoreOntModel; public MashupOntologyReader(){ // create an ontology model bookStoreOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null); } public static void main(String[] args) { MashupOntologyReader reader = new MashupOntologyReader(); } } Ở đây bạn sử dụng ModelFactory để tạo một mô hình bản thể luận. Lưu ý là Jena API đồng thời cũng là một RDF API, cho nên nó cho phép bạn tạo ra rất nhiều kiểu mô hình khác nhau. Bình thường, trong trường hợp này, bạn cần một mô hình bản thể luận, và thông qua các dữ liệu cố định được cung cấp, bạn phải xác định rõ là bạn muốn nó nằm bên trong bộ nhớ. Tải bản thể luận Jena API cho phép bạn tạo các bản thể luận từ đầu và bao gồm các phương thức cần thiết để thực hiện, trong trường hợp này, bạn đã có sẵn một tệp bản thể luận để đọc, cho nên bước tiếp theo là tải nó từ mô hình bạn vừa tạo ra (xem ví dụ 6): Ví dụ 6. Tải bản thể luận ... public class MashupOntologyReader { private OntModel bookStoreOntModel; public MashupOntologyReader(){ String source = ""; // create an ontology model bookStoreOntModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, null); // you have a local copy of the bookstore ontology bookStoreOntModel.getDocumentManager().addAltEntry( source, "file:c:/sw/stores.owl" ); // read the source document bookStoreOntModel.read( source ); } public static void main(String[] args) { MashupOntologyReader reader = new MashupOntologyReader(); } } Đầu tiên, hãy dành chỗ ghi tên cho đối tượng bạn vừa tải. Với bản thể luận bạn đã xây dựng ở phần 4, không gian tên là Từ đó bạn sử dụng của mô hình DocumentManager để thêm vào các đầu mục. Lưu ý rằng bạn chỉ rõ không gian tên và tập tin mà từ đó cho phép thâm nhập, nhưng các mô hình không thực sự đọc các định nghĩa trừ khi bạn gọi hàm read(). Duyệt qua các cá thể Mục tiêu là có được danh sách các cá thể Bookstore trong bản thể luận, vì thế bắt đầu bằng việc đi qua chuỗi tất cả các cá thể có mặt (xem ví dụ 7). Ví dụ 7. Duyệt các cá thể ... // read the source document bookStoreOntModel.read( source ); } public void getIndividuals(){ int counter = 0; for (Iterator i = bookStoreOntModel.listIndividuals(); i.hasNext(); ) { counter++; Individual thisIndividual = (Individual) i.next(); System.out.println(counter); } } public static void main(String[] args) { MashupOntologyReader reader = new MashupOntologyReader(); reader.getIndividuals(); } } Để bắt đầu, cần tạo ra một phương thức getIndividuals() mà nó sẽ tạo ra một bộ đếm và sử dụng mô hình của phương thức listIndividuals() của bản thể luận để lấy bộ lặp Iterator chuẩn của JAVA qua nó bạn có thể tiếp cận các cá thể tìm được. Bạn chưa có bất kỳ một dữ liệu nào về các cá thể do đó đơn giản cung cấp một bộ đếm để xem điều gì xảy ra. Bạn sẽ có một danh sách từ một đến mười một. Bây giờ mọi việc đều thú vị, rõ ràng bạn có nhiều hơn là các cá thể Bookstore. Hãy tìm hiểu xem bạn thật sự thu được cái gì. Có các thông tin về cá thể Khi có thông tin tham khảo của cá thể, việc thu thập các thông tin của nó là vấn đề đơn giản thông qua sử dụng các phương thức thu thập mà API cung cấp. Bất kỳ một cá thể Individual nào, cho dù là loại đối tượng nào, đều có ba loại thông tin giống nhau: URI, sử dụng duy nhất để xác định tài nguyên, kiểu, và tên, cái mà tương ứng với thuộc tính rdf:ID trong tệp RDF (xem ví dụ 8): Ví dụ 8. Lấy thông tin cá thể ... public void getIndividuals(){ int counter = 0; for (Iterator i = bookStoreOntModel.listIndividuals(); i.hasNext(); ) { counter++; Individual thisIndividual = (Individual) i.next(); String indType = thisIndividual.getRDFType().getLocalName(); String indName = thisIndividual.getLocalName(); String indResourceURI = thisIndividual.getURI(); System.out.println(indType + " " + indName + " " + indResourceURI); } } ... Bạn cần chú ý đầu ra trông giống với Ví dụ 9: Ví dụ 9. Đầu ra thông tin cá thể 0: Book Harry_Potter_and_the_Sorcerers_Stone 1: Genre Memoir 2: Genre Philosophy 3: Genre History 4: Genre Nonfiction 5: Genre Fiction 6: Author Fyodor_Dostoevsky 7: Author Joanne_Rowling 8: Author J_K_Rowling 9: Bookstore Buy.com 10: Bookstore Amazon.com 11: Bookstore BarnesAndNoble.com Chú ý rằng thứ tự các cá thể xuất hiện ở đầu ra thì không cần thiết phải giống với thứ tự chúng xuất hiện trong tệp bản thể luận. Hiện giờ chúng không là vấn đề, nhưng nếu nhúng dữ liệu vào mẫu (template) thì sẽ có vấn đề. May mắn là nếu biết trước là sẽ được chuẩn bị trước và đây là vấn đề có thể xử lý dễ dàng. Tại thời điểm này bạn chỉ lo lắng về chuyện thu thập các cá thể Bookstore. Chỉ lấy ra các Bookstores Sự thật là các kiểu tài nguyên được đại diện như một chuỗi (string) sẽ tạo điều kiện dễ dàng để lấy ra Bookstores hoặc bất kỳ kiểu cụ thể nào (xem ví dụ 10): Ví dụ 10. Chiết xuất chỉ một loại cá thể ... public Individual[] getIndividuals(String individualType){ int counter = -1; Individual[] individuals = new Individual[50]; for (Iterator i = bookStoreOntModel.listIndividuals(); i.hasNext(); ) { Individual thisIndividual = (Individual) i.next(); String indType = thisIndividual.getRDFType().getLocalName(); String indName = thisIndividual.getLocalName(); String indResourceURI = thisIndividual.getURI(); if (indType.equals(individualType)){ counter++; individuals[counter] = thisIndividual; System.out.println(counter + ": " + indType + " " + indName + " " + indResourceURI); } } return individuals; } public static void main(String[] args) { MashupOntologyReader reader = new MashupOntologyReader(); Individual[] individuals = reader.getIndividuals("Bookstore"); } } Trong trường hợp này, bạn kiểm tra kiểu đã gửi đến so với loại của từng cá thể, và nếu cá thể là một trong những loại bạn đang tìm kiếm thì bạn chuyển nó vào mảng các individuals. Sau khi bạn xem tất cả các cá thể, quay trở lại mảng như là đầu ra của phương thức. Bước tiếp theo là thêm tính năng này vào ứng dụng thực sự. Tạo ra một thực đơn từ danh sách các dịch vụ Tại thời điểm này, bạn đã sẵn sàng tiếp cận với các khả năng của Jena từ trong các ứng dụng thật của web. Trước khi bạn bắt đầu, phải chắc chắn rằng các tệp *.jar đều có thể truy cập vào từ ứng dụng của web và lớp MashupOntologyReader có sẵn cho servlet. Bổ sung chức năng sau vào phương thức doGet() (xem ví dụ 11): Ví dụ 11. Tạo ra một mẫu chọn thực đơn protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { MashupOntologyReader reader = new MashupOntologyReader(); Individual[] individuals = reader.getIndividuals("Bookstore"); response.getWriter().print(""); response.getWriter().print(""); response.getWriter().print(""); response.getWriter().print("The Mashup"); response.getWriter().print("<form action='MashupClientServlet' method='post'>"); response.getWriter().print("Choose a bookstore:"); response.getWriter().print(""); for (int i = 0; i < individuals.length; i++){ Individual thisIndividual = individuals[i]; if (thisIndividual != null){ String id = thisIndividual.getURI(); System.out.println("["+id+"]"); String label = thisIndividual.getLocalName(); System.out.println("["+label+"]"); response.getWriter().print("<option "+ "value=\""+id+"\">"+label+""); } } response.getWriter().print(""); response.getWriter().print("Enter a keyword:"); response.getWriter().print(""); response.getWriter().print(""); response.getWriter().print(""); response.getWriter().print(""); response.getWriter().print(""); } Đầu tiên, tạo một thể hiện của lớp MashupOntologyReader, cái mà cũng tải bản thể luận thực sự. Từ đó bạn có thể sử dụng phương thức getIndividuals() bạn vừa tạo ra để thu được một mảng Bookstore. Khi bạn đã có mảng Bookstore bạn có thể lặp vòng chúng nếu bạn muốn các mảng khác sử dụng cùng phương thức trước khi thu lại được URI và tên hoặc ID. Sử dụng chúng để tạo ra thực đơn HTML select trong mẫu có sẵn. Kết quả cuối cùng trông giống hình 1 Hình 1. Thêm vào hộp lựa chọn Gửi biểu mẫu và dịch vụ đầu ra Lấy dịch vụ mà người sử dụng muốn sử dụng là việc rất giản đơn. Thực tế, nó không khác với lấy lại bất cứ thông tin nào đã gửi từ một biểu mẫu (xem ví dụ 12): Ví dụ 12. Lấy lại thông tin từ mẫu thông tin ... protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String query = request.getParameter("query").toString(); String serviceURI = request.getParameter("serviceURI").toString(); Service service = ont.obtainServiceInfo(serviceURI); response.getWriter().print("Results pulled from " +serviceURI+""); try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); ... Một cách đơn giản, lấy serviceURI như là một tham số từ mẫu. Bạn có thể cung cấp nó tới trang để bảo đảm nó hoạt động được. Bây giờ bạn có thể sẵn sàng lấy lại thông tin dịch vụ thực tế. Lấy lại dịch vụ thông tin từ bản thể luận Giờ bạn đã biết loại dịch vụ nào người sử dụng muốn dùng, bạn sẽ cần phải lấy thông tin về nó từ bản thể luận. Để làm vậy, bạn cần thêm API đối với phương thức doPost(). Bổ sung thông tin dịch vụ vào bản thể luận Khi bạn xây dựng bản thể luận ở Phần 4, đã bao gồm thông tin dịch vụ căn bản, nhưng bây giờ phải chi tiết hơn một chút. Đặc biệt, phải thêm vào các thông tin bổ sung về dịch vụ, chẳng hạn như mẫu và bản ghi dữ liệu hiển thị đang tồn tại ở thời điểm lớp Service hiện tại cũng như một cách để tập hợp các tham số bổ sung cho một dịch vụ, chẳng hạn như các kiểu tìm kiếm hoặc một mã phát triển (developer token). Ví dụ 13. Làm rõ trên định nghĩa về dịch vụ ... Web Service <owl:minCardinality rdf:datatype= "&xsd;nonNegativeInteger">1 <owl:minCardinality rdf:datatype= "&xsd;nonNegativeInteger">1 <rdfs:range rdf:resource= ""/> Web Service Parameter Map <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">1 <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">1 ... Bất cứ thông tin nào như mẫu ghi các hồ sơ hiển thị (ở đây gọi là rootnode) khá là dễ hiểu. Bạn chỉ cần thêm vào như một thuộc tính của lớp. Ở một số trường hợp, tình trạng không đơn giản như thế. Ví dụ, nhập các thông số đầu vào cần cả tên và giá trị, cho nên bạn phải xây dựng cấu trúc để có đủ các thông tin như vậy. Trong trường hợp này, cấu trúc này được gọi là ServiceParameterMap. ServiceParameterMap tham chiếu với tài nguyên paramname và paramvalue. Với toàn bộ các thuộc tính đã được tạo ra, bây giờ bạn có thể thiết lập các cá thể thực tế. Dịch vụ riêng biệt trong bản thể luận Tạo các cá thể dịch vụ thực tế khá đơn giản, chỉ cần theo cấu trúc các lớp (xem ví dụ 14). Ví dụ 14. Tạo ra cá thể hiệu sách /ItemSearchResponse/Items/Item <![CDATA[ TBD ]]> <![CDATA[ by ]]> ItemAttributes/Title!ItemAttributes/Author DetailPageURL Title Service AWSECommerceService AWSAccessKeyId 000000000000000 SearchIndex Books ResponseGroup Large Operation ItemSearch Một số đặc tính, ví dụ mẫu và elementValue bạn cần nhận ra từ lớp Service. Các lớp khác, ví dụ như tài nguyên inputparameter là mới và được tạo ra như là các ví dụ riêng biệt của lớp ServiceParameterMap, sau đó được tham khảo từ trong phần chính của cá thể dịch vụ như đặc tính inputparameter. Ngoài ra có vẻ sẽ là tốt nếu thêm mỗi elementValue và attributeValue trong chính đặc tính của nó, nó sẽ gây ra rắc rối vì bạn không thể dự đoán thứ tự nào chúng có thể được lấy lại, nhưng bạn phải chắc chắn thứ tự mà chúng xuất hiện. Để xử lý vấn đề này, bao gồm cả tất cả các giá trị, được tách ra bởi một dấu chấm than (!). Dấu chấm than có vẻ sẽ không xuất hiện trong các biểu thức XPath, mà sau này bạn có thể sử dụng nó như là một dấu phân cách. Chú ý bạn có thể đơn giản cho thêm vào một tham số đối với điểm cuối cùng, nhưng làm như vậy bạn sẽ có rất nhiều lợi ích. Một là bạn có thể chọn linh hoạt các tham số như là nguyên tắc của nhân tố phát triển (developer key), hai là cấu trúc của bạn được đồng nhất hơn và do đó dễ dàng trong việc áp dụng các ứng dụng cho các dịch vụ SOAP cũng nhưng REST. Bây giờ hãy nhìn các thông tin thu được. Thu lại các cá thể Bước đầu tiên là tìm các tham khảo đối với tài nguyên đại diện cho cá thể ở trong bản thể luận. Do các giá trị quay lại bởi hộp lựa chọn là URI cho tài nguyên, việc lựa chọn là tương đối dễ dàng (xem ví dụ 15): Ví dụ 15. Thu lại các cá thể ... public class MashupOntologyReader { private OntModel bookStoreOntModel; public MashupOntologyReader(){ ... } public Individual[] getIndividuals(String individualType){ ... return individuals; } public void obtainServiceInfo(String serviceURI){ Individual bookstore = bookStoreOntModel.getIndividual(serviceURI); } } public static void main(String[] args) { MashupOntologyReader reader = new MashupOntologyReader(); Individual[] individuals = reader.getIndividuals("Bookstore"); reader.obtainServiceInfo( ""); } } Tạo một phương thức mới, obtainServiceInfo() trong lớp MashupOntologyGreater và sử dụng phương thức getIndividual() để lấy lại tài liệu tham khảo đối với tài nguyên cụ thể. Từ đây bạn có thể lấy ra các thông tin về chính dịch vụ đó. Thu lại các tham số dịch vụ Các tham biến dịch vụ được lưu như là đặc tính của tài nguyên đại diện cho dịch vụ do đó bạn phải tiếp cận những đặc tính này để lấy thông tin (xem ví dụ 16): Ví dụ 16. Lấy các tham biến dịch vụ ... public class MashupOntologyReader { private OntModel bookStoreOntModel; public MashupOntologyReader(){ ... } public Individual[] getIndividuals(String individualType){ ... return individuals; } public void obtainServiceInfo(String serviceURI){ Individual bookstore = bookStoreOntModel.getIndividual(serviceURI); for (StmtIterator i = bookstore.listProperties( ); i.hasNext(); ) { Statement s = i.nextStatement(); Property p = s.getPredicate(); if (p.canAs(OntProperty.class)){ Resource r; Literal l; if (p.getLocalName().equals("endpoint")){ l = s.getLiteral(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("rootoutputnode")){ l = s.getLiteral(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("inputparameter")){ r = s.getResource(); System.out.println( getParameterName(r.getURI()) + " ==> " + getParameterValue(r.getURI())); } else if (p.getLocalName() .equals("xsltTransformationString")){ l = s.getLiteral(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("template")){ l = s.getLiteral(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("elementValue")){ l = s.getLiteral(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("attributeValue")){ l = s.getLiteral(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("queryParameter")){ l = s.getLiteral(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } } } } public String getParameterName(String uri){ // this assumes the uri is to a ServiceParameterMap OntResource or = bookStoreOntModel.getOntResource(uri); String toReturn=null; for (StmtIterator i = or.listProperties( ); i.hasNext(); ) { Statement s = i.nextStatement(); Property p = s.getPredicate(); if (p.canAs(OntProperty.class)){ Resource r; Literal l; if (p.getLocalName().equals("paramname")){ l = s.getLiteral(); toReturn=l.getString(); } } } return toReturn; } public String getParameterValue(String uri){ // this assumes the uri is to a ServiceParameterMap OntResource or = bookStoreOntModel.getOntResource(uri); String toReturn=null; for (StmtIterator i = or.listProperties( ); i.hasNext(); ) { Statement s = i.nextStatement(); Property p = s.getPredicate(); if (p.canAs(OntProperty.class)){ Resource r; Literal l; if (p.getLocalName().equals("paramvalue")){ l = s.getLiteral(); toReturn=l.getString(); } } } return toReturn; } public static void main(String[] args) { MashupOntologyReader reader = new MashupOntologyReader(); Individual[] individuals = reader.getIndividuals("Bookstore"); reader.obtainServiceInfo( ""); } } Đáng tiếc, bạn không thể chỉ đơn giản vào và nhặt lấy các đặc tính. Thay vào đó, bạn phải lặp lại tất cả các đặc tính sử dụng phương thức listProperties() mà nó sẽ trả lại cho một bộ lặp Iterator. Bạn phải nhớ rằng trong RDF, các thuộc tính được trình bày dưới dạng các câu hoặc các câu lệnh ví dụ như "The Amazon.com service has an endpoint of " Sử dụng ngữ pháp một cách thông minh, cụm "has an endpoint of " là phần thuộc tính của câu. Do đó, bước đầu tiên để truy lục các thuộc tính là truy lục câu lệnh, sau đó truy lục các thuộc tính từ đây. Khi bạn đã có các thuộc tính, đầu tiên bạn cần chắc chắn rằng thực tế đó là thuộc tính bản thể luận. Sau cùng, đó có thể là một thuộc tính RDF hoặc một thuộc tính bất thường khác. Khi bạn chắc rằng đó là một thuộc tính bản thể luận, bạn có thể truy vấn localName và so sánh nó với các tham số mà bạn mong đợi. Khi bạn biết mình đang xử lý thuộc tính nào thì việc bạn làm gì phụ thuộc vào thể loại thuộc tính đó. Một số đặc tính như mẫu (template), đơn giản là các chuỗi ký tự bằng chữ, và bạn có thể trích ra như vậy. Tuy nhiên, một số thuộc tính khác như inputparameter là các tài nguyên, do đó bạn không thể đơn giản trích các giá trị bằng chữ từ đây. Thay vào đó, bạn cần trích các thuộc tính của chúng. Ví dụ inputparameter bao gồm một mục tiêu cùng với một thuộc tính paramname và paramvalue. Để tìm các thuộc tính này, bạn có thể thiết kế phương thức getParameterName() và getParameterValue() mà lặp chính nó thông qua các thuộc tính của tài nguyên chủ thể. Khi ta chạy ứng dụng, bạn sẽ có kết quả tương tự như hình 2: Hình 2. Thông tin dịch vụ Lớp dịch vụ được cập nhật Tất cả các thông tin này không tốt với bạn trừ khi nó được lưu đâu đó mà bạn có thể có được. Ứng dụng hiện được cài đặt để phân tích và chạy một mảng các mục tiêu dịch vụ, vì vậy dự đoán tốt nhất là chỉnh sửa lớp dịch vụ sao cho nó có thể lưu trữ dữ liệu (xem ví dụ 17): Ví dụ 17. Lớp dịch vụ được cập nhật import java.util.Vector; public class Service { String name = "; String baseURL = "; String template = "; Vector inputParameters = new Vector(); String queryParameter = ""; String recordExp = ""; String xsltTransformationString = ""; Vector elementValues = new Vector(); Vector attributeValues = new Vector(); String filterExp = ""; Service subSvc = null; } Mục đích của lớp dịch vụ nguyên bản là cung cấp một nơi lưu dữ liệu, thuyết minh các mục tiêu bất kỳ và gửi chúng lại. Bạn sẽ không phải làm như vậy nữa - mọi dữ liệu có từ bản thể luận. Tất cả những gì bạn cần làm là chắc chắn bạn có các tham số thành viên cho mỗi mảng dữ liệu mà bạn muốn lưu trữ, như là inputparameters và xsltTransformationString. Tương tự, để làm các lớp dịch vụ linh động hơn, thay đổi elementValues và attributeValues thành các Vector, chứ không phải các mảng kích thước cố định, như lúc trước đây của chúng. Bây giờ bạn có thể tạo dịch vụ . Tạo dịch vụ Bạn vừa hoàn thành công việc khó khăn là trích xuất dữ liệu từ bản thể luận. Những gì bạn cần làm bây giờ là tạo một mục tiêu dịch vụ mới và sau đó thêm các thông tin vào đó (xem ví dụ 18): Ví dụ 18. Tạo dịch vụ ... public Service obtainServiceInfo(String serviceURI){ Individual bookstore = bookStoreOntModel.getIndividual(serviceURI); Service svc = new Service(); for (StmtIterator i = bookstore.listProperties( ); i.hasNext(); ) { Statement s = i.nextStatement(); Property p = s.getPredicate(); if (p.canAs(OntProperty.class)){ Resource r; Literal l; if (p.getLocalName().equals("endpoint")){ l = s.getLiteral(); svc.baseURL=l.getString(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("rootoutputnode")){ l = s.getLiteral(); svc.recordExp=l.getString(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("inputparameter")){ r = s.getResource(); svc.inputParameters.add(r.getURI()); System.out.println( getParameterName(r.getURI()) + " ==> " + getParameterValue(r.getURI())); } else if (p.getLocalName() .equals("xsltTransformationString")){ l = s.getLiteral(); svc.xsltTransformationString=l.getString(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("template")){ l = s.getLiteral(); svc.template=l.getString(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("elementValue")){ l = s.getLiteral(); String[] elementValues = l.getString().split("!"); for (int j = elementValues.length; j>0; j--){ svc.elementValues.add(elementValues[(j-1)]); } System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("attributeValue")){ l = s.getLiteral(); String[] attributeValues = l.getString().split("!"); for (int j = attributeValues.length; j>0; j--){ svc.attributeValues.add(attributeValues[(j-1)]); } System.out.println( p.getLocalName() + " ==> " + l.getString() ); } else if (p.getLocalName().equals("queryParameter")){ l = s.getLiteral(); svc.queryParameter = l.getString(); System.out.println( p.getLocalName() + " ==> " + l.getString() ); } } } return svc; } ... Lưu ý rằng bạn nắm được sự khác nhau của các tên giữa lớp dịch vụ và bản thể luận trong phương thức này. Ví dụ, bạn đã vạch ra endpoint đối với baseURL. Cũng lưu ý rằng, trong khi bạn có thể thêm chuỗi các chữ ví dụ như mẫu trực tiếp đối với lớp, bất cứ đặc tính được đại diện như là một tài nguyên, ví như inputparameter có thêm những thứ không phải là ký tự chữ, mà như URI đối với tài nguyên. (Bạn có thể quyết định các ứng dụng của mình sẽ có lợi từ tất cả thông tin chứa trực tiếp giữa các lớp. Trong tình huống đó, bạn cần chế tác thêm tại điểm này). Bạn cũng có thể phân chia các giá trị trong thuộc tính elementValue và attributeValue thành một mảng, và sau đó sử dụng mảng để tạo dịch vụ. Bước tiếp theo là xây dựng yêu cầu REST thực. Xây dựng yêu cầu Lúc này, bạn có tất cả thông tin dịch vụ, nhưng bạn không có một yêu cầu có thể gửi trực tiếp đến dịch vụ, vì tất cả các tham số đầu vào đã bị tách thành các tài nguyên riêng lẻ. Việc tạo ra yêu cầu này là một đặc tính đối với dịch vụ, và không phải một phần của bản thể luận hay servlet, vì vậy bao gồm nó như một phần của lớp dịch vụ (xem ví dụ 19): Ví dụ 19. Xây dựng yêu cầu import java.util.Vector; public class Service { String name = ""; ... public String getRESTRequest(MashupOntologyReader ont){ String restQuery = this.baseURL; for (int i=0;i<this.inputParameters.size();i++){ String serviceParameterMapURI = (String) this.inputParameters.elementAt(i); if (restQuery.equals(this.baseURL)) restQuery = restQuery + "?"; else restQuery = restQuery + "&"; restQuery = restQuery + ont.getParameterName(serviceParameterMapURI) + "=" + ont.getParameterValue(serviceParameterMapURI); } restQuery = restQuery + "&" + this.queryParameter + "="; return restQuery; } } Trong phương thức getRESTRequest(), bạn lặp qua mỗi inputParameters, thêm chúng vào baseURL. Cuối cùng, cuối URL, bạn thêm các tham số truy vấn thực và một tín hiệu ngang bằng (=). Theo cách này, khi bạn thêm các từ khoá để tìm đến hết truy vấn, bạn có một truy vấn URL đầy đủ như: AWSECommerceService&AWSAccess KeyId=000000000000000&SearchIndex= Books&Operation=ItemSearch&Title=Star+Wars Lưu ý: Mã gốc là một dòng đơn thông thường. Để dễ nhìn, nó được diễn tả trên nhiều dòng như trên. Tạo các yêu cầu Thực ra, việc tạo các yêu cầu được tiến hành hầu như giống hệt như trước (xem ví dụ 20): Ví dụ 20. Tạo yêu cầu ... protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { MashupOntologyReader ont = new MashupOntologyReader(); String query = request.getParameter("query").toString(); String serviceURI = request.getParameter("serviceURI").toString(); Service service = ont.obtainServiceInfo(serviceURI); try { DocumentBuilder builder = DocumentBuilderFactory.newInstance() .newDocumentBuilder(); Service[] svcs = {service}; Document hostDoc = builder.parse( new InputSource(new StringReader(""))); Node hostRoot = hostDoc.getDocumentElement(); for (int k=0; k < svcs.length; k++){ Service svc = svcs[k]; Node renderedService = renderService(svc.getRESTRequest(ont)+query, hostDoc); if (renderedService != null){ Element nameElement = hostDoc.createElement("h1"); nameElement.appendChild( hostDoc.createTextNode(svc.name)); ... Đầu tiên, bạn cần mở bản thể luận - bạn cũng cần nó để đặt dịch vụ vào, và tạo yêu cầu REST. Khi bạn đã đặt dịch vụ vào rồi, bạn có thể sử dụng nó để thay thế các thành phần trong mảng dịch vụ với một thành phần đơn nhất. Từ đây, mọi thứ tiến hành như trước, trừ khi bạn tạo truy vấn khi bạn sử dụng dịch vụ renderService(). Bây giờ bạn có thể chạy ứng dụng và có kết quả tương tự với những gì được tạo ra trong phiên bản ứng dụng cơ bản hơn. Chuyển đổi kết quả Tới đây, những gì bạn cần hoàn tất là thay đổi ứng dụng nhận thông tin như thế nào về dịch vụ. Nó vẫn yêu cầu thông tin như vậy, và nó triển khai thông tin thô được trả lại từ dịch vụ. Bước tiếp theo là chuyển đổi thông tin đặc tính dịch vụ thành thông tin dạng bản thể luận tổng quát (generic ontological information). Đầu vào Hãy cùng bắt đầu bằng cách xem dữ liệu được trả về từ yêu cầu thực. Dịch vụ mạng Amazon thực tế đưa cho bạn một sự lựa chọn về lượng dữ liệu bạn muốn được gửi lại là bao nhiêu, bằng cách chọn một ResponseGroup của Small, bạn sẽ có thông tin cơ bản nhất, cái mà ít cồng kềnh để xử lý hơn là một kết quả đầy đủ. Không may rằng bạn sẽ cần yêu cầu một ResponseGroup của Large để có thông tin về giá. Dữ liệu trả lại có dạng như sau (xem Ví dụ 21): Ví dụ 21. Dữ liệu thô <ItemSearchResponse xmlns= ""> ... ... 17717 1772 0307337332 07337332%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26lo cation=/o /ASIN/0307337332%253FSubscriptionId=000000000000000 16 ... ... ... ... Cesar Millan Hardcover Asdf Melissa Jo Peltier 636.70887 9780307337337 RAO 0307337332 Harmony 2495 USD $24.95 Harmony 1 234 Cesar's Way: The Natural, Everyday Guide to Understanding and Correcting Common Dog Problems ... 0060817089 ... Tất nhiên, bạn đủ khả năng để thêm các thông tin này vào bản thể luận của bạn, nhưng vì mục đích của bài viết này, nên gắn với các vấn đề cơ bản. Kết quả đích Mục tiêu tổng thể là nắm được thông tin và chuyển đổi nó thành một dạng phù hợp với bản thể luận. Trong trường hợp này, trông nó sẽ như sau (xem ví dụ 22): Ví dụ 22. Mục tiêu đầu ra <rdf:RDF xmlns:res= "" xmlns:rdf=""> Cesar Millan Cesar's Way: The Natural, Everyday Guide to Understanding and Correcting Common Dog Problems <itemPrice rdf:datatype= "">24.95 07337332%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o /ASIN/0307337332%253FSubscriptionId=000000000000000 John Grogan ... Một vài mục cần lưu ý ở đây. Đầu tiên là Book có một mã số bao gồm số xuất bản (ISBN). Số này là duy nhất trong tất cả dịch vụ. Trong một quy trình sản xuất, bạn muốn kiểm tra để chắc chắn rằng yếu tố này không tồn tại trước khi bạn tạo lại nó; có thể rằng cuốn sách tương tự đã có yêu cầu từ dịch vụ khác, hoặc thậm chí một truy vấn khác từ dịch vụ tương tự. Tương tự, mã này tránh được sự trùng lặp các yếu tố tác giả bằng cách chưa xử lý trước số xuất bản với tên tác giả trong mã số. Cũng như vậy, bạn sẽ phải xử lý với thực tế rằng một giá trị mã số không thể có các khoảng cách trong đó. StockItem tham chiếu ngược lại Book thông qua đặc tính stockProduct cái mà chứng nhận là những tài nguyên thích hợp. Khi bạn đã chuyển dữ liệu sang dạng này, bạn có thể lưu nó trong cơ sở dữ liệu và phân tích nó bằng cách sử dụng công cụ dạng bản thể luận. Bạn sẽ hoàn tất sự chuyển đổi bằng cách sử dụng bộ chuyển đổi XSLT. Bảng định kiểu Bảng định kiểu (Stylesheet) là một trang dùng để định dạng điển hình, nhưng sử dụng một cặp chức năng XPath để hoàn thành một vài tác vụ khó hơn (xem ví dụ 23): Ví dụ 23. The stylesheet <xsl:stylesheet version="1.0" xmlns:xsl="" xmlns:res= "" xmlns:rdf = ""> <xsl:apply-templates select= "/res:ItemSearchResponse/res:Items/res:Item" /> <xsl:value-of select= "translate(res:ItemAttributes/res:Author, ' ', '_' )"/> <xsl:value-of select="res:ASIN"/><xsl:value-of select= "translate(res:ItemAttributes/res:Author, ' ', '_' )"/> AMAZON_<xsl:value-of select= "res:ASIN"/> #<xsl:value-of select= "res:ASIN"/> <itemPrice rdf:datatype= ""><xsl:value-of select="translate(res:ItemAttributes/res:ListPrice/res:FormattedPrice, '$', '')"/> <xsl:value-of select= "res:ItemAttributes/res:Title"/> Đầu tiên bảng định kiểu tạo thành phần chính RDF, hoạt động như là khởi nguồn của tài liệu. Từ đây, nó lặp lại thông qua từng thành phần Item và tạo ra các thành phần Author, Book, và StockItem. Khi cần thiết nó sử dụng hàm translate() để thay thế những khoảng trống trong tên tác giả bằng dấu gạch chân. Lưu ý cách dùng của các chuỗi ký tự bằng chữ như là AMAZON_. Do sự chuyển đổi này là đặc tính của dịch vụ, bạn có thể thực hiện việc chuyển đổi mà không bị sao. Tạo một ứng dụng thử nghiệm Bây giờ bạn gần như sẵn sàng để bắt đầu sự chuyển đổi, nhưng do gần như không thể xem những gì xảy ra giữa các servlet, nên tạo ra một lớp kiểm tra để chạy sự chuyển đổi và chắc chắn nó hoạt động đúng cách (xem ví dụ 24). Ví dụ 24. Tạo lớp thử nghiệm import java.io.IOException; import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.xml.sax.InputSource; import java.io.PrintStream; public class DoThis { public static void main (String args[]){ String transString= "<xsl:stylesheet version=\"1.0\" "+ ... try { } catch (Exception e){ e.printStackTrace(); } } } Đây chỉ là một lớp đơn giản, nhưng do bảng định kiểu cuối cùng sẽ bị tiếp cận như là một chuỗi (như là một đặc tính của lớp Service). Xây dựng tài liệu gốc Để bắt đầu sự chuyển đổi, tạo DOMSource bằng cách phân tích cú pháp các kết quả của yêu cầu thực (xem ví dụ 25): Ví dụ 25. Xây dựng DOMSource ... try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse( " WSAccessKeyId=000000000000000&SearchIndex=Books&Operation=ItemSe arch&ResponseGroup=Large&Title=Dogs"); Source xmlSource = new DOMSource(document); } catch (Exception e){ e.printStackTrace(); } } URL đang được phân tích là URL được tạo ra bởi phương thức getRESTRequest() nhưng để mọi thứ hoạt động đúng đắn, bạn cần chắc chắn rằng DocumentBuilderFactory tạo một DocumentBuilder mà nhận ra các khoảng trống. Nếu không, chương trình phân tích sẽ không hiểu các thành phần bảng định kiểu nên được xử lý như là một bảng định kiểu. Tạo bảng định kiểu Bạn cần tạo một DOMSource cái mà đại diện cho bảng định kiểu (xem ví dụ 26): Ví dụ 26. Tạo đối tượng bảng định kiểu ... Source xmlSource = new DOMSource(document); Document xslDoc = builder.parse( new InputSource(new StringReader(transString))); DOMSource xslSource = new DOMSource(xslDoc); TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(xslSource); } catch (Exception e){ e.printStackTrace(); } } Tất nhiên trong ứng dụng thực, bạn sẽ thay thế transString bằng xsltTransformationString từ Service. Chuyển đổi tài liệu Bây giờ bạn cần thực hiện sự chuyển đổi thực (xem ví dụ 27): Ví dụ 27. Thực hiện chuyển đổi ... TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(xslSource); StreamResult result = new StreamResult(System.out); transformer.transform(xmlSource, result); } catch (Exception e){ e.printStackTrace(); } } Bạn đang thiết lập kết quả là System.out do đó bạn sẽ thấy các cá thể của bản thể luận xuất hiện trong dòng lệnh, hoặc cửa sổ bảng điều khiển, như bạn thấy trong hình 3. Hình 3. Kết quả của sự chuyển đổi Hiển thị các kết quả Cuối cùng bạn đã gần hoàn thành. Bạn có thể truy xuất thông tin dịch vụ từ bản thể luận, thiết lập yêu cầu, và chuyển đổi kết quả sang thông tin dạng bản thể luận. Bây giờ bạn chỉ phải trình bày thông tin loại dạng bản thể luận như là bộ phận của một ứng dụng. Quy trình hiển thị hoạt động như thế nào Đến đây có thể là lúc để rà soát xem quy trình hiển thị thực sự hoạt động thế nào. Mọi yêu cầu dịch vụ trả lại một khối lớn XML. Mục tiêu là để hiển thị các phần cụ thể của khối này trên một trang HTML. Có nghĩa rằng bạn sẽ kết hợp dữ liệu với các thẻ HTML. Đối với mỗi dịch vụ, bạn xác định một mẫu, một chuỗi mã HTML bao gồm các trình giữ chỗ (placeholders) trong đó mà bạn có thể thả các dữ liệu thích hợp vào. Ví dụ, mẫu bạn đang sử dụng đối với dịch vụ Amazon là (xem ví dụ 28): Ví dụ 28. Mẫu by Bạn thấy hai thành phần value và một thuộc tính value . Khi bạn xử lý dịch vụ, bạn sẽ thay thế các nút này bằng thông tin cụ thể từ dịch vụ. Ví dụ, bạn muốn thành phần value đầu tiên để đại diện cho tiêu đề, nên bạn sẽ thay thế nó bằng nút tìm được trong kết quả REST tại /ItemSearchResponse/Items/Item/ItemAttributes/Title. Bạn biết đó là dữ liệu bạn cần vì recordExp được thiết lập tới /ItemSearchResponse/Items/Item, hoạt động như nguồn gốc khởi đầu của trường hợp này, và là elementValue đầu tiên được thiết lập ItemAttributes/Title. Để mọi thứ xảy ra với dữ liệu được chuyển đổi, bạn cần phải làm như sau: 1. Thêm thông tin chuyển đổi vào bản thể luận, và cả dịch vụ. 2. Tạo yêu cầu. 3. Chuyển đổi yêu cầu thô sang thông tin dạng bản thể luận. 4. Trích dẫn thông tin phù hợp từ thông tin dạng bản thể luận. 5. Chèn các thông tin thu được vào mẫu. 6. Hiển thị mẫu Hãy bắt đầu bằng cách chắc chắn rằng thông tin dịch vụ trong bản thể luận là mới cập nhật. Điều chỉnh đầu vào tổng quát Điều đầu tiên bạn cần làm là thêm bảng định kiểu XSLT vào xsltTransformationString một cách đúng đắn, nhưng trước khi làm như vậy hãy cân nhắc thêm một khía cạnh. Bản thể luận được xây dựng để phục vụ một mục đích cụ thể, và phục vụ tốt mục đích đó, nhưng nó không đưa chính nó vào biểu thức XPath. Vì mục đích của bài viết này - bạn không cần đưa hết tất cả các phần vào biểu thức XPath khó hiểu - tạo một sự thay đổi đối với bảng định kiểu để đơn giản hoá đầu ra. Bạn có một đầu ra mới trông như sau (xem ví dụ 29): Ví dụ 29. Cấu trúc dữ liệu mới Cesar's Way: The Natural, Everyday Guide to Understanding and Correcting Common Dog Problems Cesar Millan 7332%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/030733733 2%253FSubscriptionId=000000000000000 Marley amp; Me: Life and Love with the World's Worst Dog John Grogan 7089%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/006081708 9%253FSubscriptionId=000000000000000 ... To set that up, add the following stylesheet to the ontology (see Listing 30): Listing 30. Adding the stylesheet to the ontology ... //Book <![CDATA[ <xsl:stylesheet version="1.0" xmlns:xsl="" xmlns:res= "" xmlns:rdf = ""> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:apply-templates select= "/res:ItemSearchResponse/res:Items/res:Item" /> <xsl:value-of select= "res:ItemAttributes/res:Title"/> <xsl:value-of select= "res:ItemAttributes/res:Author"/> <xsl:value-of select= "res:DetailPageURL"/> ]]> by ]]> ItemAttributes/Title!ItemAttributes/Author DetailPageURL Title Service AWSECommerceService ... Để thiết lập cấu trúc đó, thêm bảng định kiểu sau vào bản thể luận (xem ví dụ 30): Ví dụ 30. Thêm bảng định kiểu vào bản thể luận ... //Book <![CDATA[ <xsl:stylesheet version="1.0" xmlns:xsl="" xmlns:res= "" xmlns:rdf = ""> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:apply-templates select= "/res:ItemSearchResponse/res:Items/res:Item" /> <xsl:value-of select= "res:ItemAttributes/res:Title"/> <xsl:value-of select= "res:ItemAttributes/res:Author"/> <xsl:value-of select= "res:DetailPageURL"/> ]]> by ]]> ItemAttributes/Title!ItemAttributes/Author DetailPageURL Title Service AWSECommerceService ... Bây giờ bạn đã sẵn sàng thực hiện chuyển đổi trên phản hồi dịch vụ. Chuyển đổi kết quả dịch vụ cụ thể Sự chuyển đổi dữ liệu thô sang dữ liệu có ý nghĩa nên trong suốt; nó xảy ra như một phần của quy trình tổng thể của dịch vụ (xem ví dụ 31): Ví dụ 31. Chuyển đổi phản hồi ... public class MashupClientServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { ... public static Document getData (String query, Service svc) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); String cached = checkCache(query); Document document = null; if (cached.equals("-1")){ //Using fresh data Document inputDocument = builder.parse(query); try { Source xmlSource = new DOMSource(inputDocument); Document xslDoc = builder.parse( new InputSource(new StringReader(svc.xsltTransformationString))); DOMSource xslSource = new DOMSource(xslDoc); TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transformer = transFactory.newTransformer(xslSource); DOMResult result = new DOMResult(); transformer.transform(xmlSource, result); document = (Document)result.getNode(); } catch (Exception e){ e.printStackTrace(); } saveData(query, document); } else{ //Using cached data, I hope Document cachedDocument; ... } public static Node renderService(String query, Service svc, Document hostDoc){ Document document = getData(query, svc); if (document != null){ ... } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { MashupOntologyReader ont = new MashupOntologyReader(); String query = request.getParameter("query").toString(); String serviceURI = request.getParameter("serviceURI").toString(); Service service = ont.obtainServiceInfo(serviceURI); try { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Service[] svcs = {service}; Document hostDoc = builder.parse( new InputSource(new StringReader(""))); Node hostRoot = hostDoc.getDocumentElement(); for (int k=0; k < svcs.length; k++){ Service svc = svcs[k]; Node renderedService = renderService( svc.getRESTRequest(ont)+query, svc, hostDoc); if (renderedService != null){ Element nameElement = hostDoc.createElement("h1"); nameElement.appendChild( hostDoc.createTextNode(svc.name)); ... Mã này chỉ ra một số thay đổi, do vậy hãy bắt đầu từ cuối và làm ngược trở lại. Đầu tiên, do thông tin cần thiết cho việc chuyển đổi là một phần của Service, bạn cần phải chuyển nó như là một phần của lời gọi đến hàm renderService(). Có nghĩa bạn cần phải bổ sung nó vào chữ ký renderService(). Khi nó đã ở đấy, bạn có thể chuyển nó tới phương thức getData() nơi mà bạn thực sự cần nó. Trong phương thức getData(), đầu tiên bạn tạo ra DocumentBuilder (lại như trong namespace-aware). Từ đó, bạn sử dụng nó để tạo ra nguồn DOMSource, lần này sử dụng Document được tạo ra khi bạn phân tách các truy vấn. Từ đó, tất cả sẽ được tiếp tục như trước đây ngoại trừ rằng bảng định kiểu đến từ Service. Sau khi có kết quả, bạn có thể lấy lại DOM Document từ nó sử dụng phương thức getNode(). Khi bạn có nó, bạn có thể tiếp tục như trước đây, lưu dữ liệu vào cơ sở dữ liệu và chuyển nó quay lại ứng dụng chính như thể chưa có gì xảy ra với nó. Điều chỉnh các tham số dịch vụ Nếu hiện giờ bạn chạy servlet, tuy nhiên, bạn sẽ thấy có vẻ không thu được kết quả gì. Tại sao? Do tại thời điểm hiện nay servlet đang cố gắng nhúng vào dữ liệu từ /ItemSearchResponse/Items/Item/ItemAttributes/Title và những cái tương tự vào mẫu, nhưng dữ liệu này không còn tồn tại bởi vì bạn đã chuyển hóa nó vào một dạng thức mới. Vì vậy để có thể thực hiện, bạn cần điều chỉnh các biểu thức XPath (xem ví dụ 32): Ví dụ 32. Điều chỉnh các biểu thức XPath ... //Book ... <![CDATA[ ... ]]> <a value='href'> by ]]> itemDescription!Author itemDetailURL Title ... Giờ thì bạn tìm kiếm dữ liệu kiểu như //Book/itemDescription tồn tại trong kiểu dạng dữ liệu đã chuyển hóa, do đó mọi thứ có vẻ trông hoàn chỉnh. Kết quả cuối cùng trông giống hình 4: Hình 4. Kết quả cuối cùng Tổng kết Và từ đây bạn sẽ đi tới đâu Mục đích của bài viết này là điều chỉnh ứng dụng để người dùng có thể lựa chọn loại dịch vụ mà họ muốn và trong một khoảng thời gian nhất định có thể hoàn thành được việc này. Bạn có thể tạo nên một số lượng bất kỳ các hiệu sách dựa trên REST cho người sử dụng bằng cách đơn giản là thêm vào các thông tin của chúng trong tệp bản thể luận. Bạn cũng có thể mở rộng dịch vụ này thành các loại dịch vụ khác tệp. Tất cả cần làm là chỉ bổ sung chúng vào bản thể luận và thay đổi kiểu mà bạn đang tìm kiếm khi bạn tạo nên mẫu. Chúng ta chưa thảo luận về các dịch vụ phụ trong bài viết này, bởi vì vấn đề là không còn đủ chỗ nữa. Các dịch vụ phụ hoạt động như trước đây. Chúng ta vẫn chưa đề cập gì về tìm kiếm các thông tin ngôn ngữ đã được phát triển trước đây. Bạn có thể lấy mã trong bài viết này và sử dụng chúng để tìm kiếm, như là các quyển sách giá thấp nhất trong cơ sở dữ liệu, độc lập với dịch vụ ở chỗ là dữ liệu được lấy lại, sử dụng cùng các công nghệ như nhau mà bạn đã học ở Phần 2 Trong bài bài viết này, bạn đã tạo cho người dùng cơ hội lựa chọn từ một số lượng hạn chế các dịch vụ xác định của một kiểu nhất định tùy chọn, lấy lại các dữ liệu thô và trả nó lại dữ liệu bản thể luận đánh dấu dưới hình thức ngôn ngữ. Ở Phần 6 bạn sẽ học cách làm thế nào để tạo cho người dùng lựa chọn loại dịch vụ nào được sử dụng và loại dữ liệu nào được trình bày cũng như là làm thế nào để trình diễn dữ liệu trên trang web.

Các file đính kèm theo tài liệu này:

  • pdfUltimate mashup – Các dịch vụ Web và Web ngữ nghĩa, Phần 5.pdf
Tài liệu liên quan