Tải bản đầy đủ (.pdf) (92 trang)

Ultimate mashup – Các dịch vụ Web và Web ngữ nghĩa (semantic Web), Phần 6 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (537.87 KB, 92 trang )

Ultimate mashup – Các dịch vụ Web và Web ngữ nghĩa (semantic Web),
Phần 6: Cho người dùng quyền kiểm soát
Tóm tắt: Đây là bài viết cuối cùng trong một loạt các bài viết để chỉ cho bạn cách
tạo một ứng dụng mashup. Ở đây, bạn cần có một ứng dụng đang chạy và một
khung làm việc thay thế nhờ đó hệ thống có thể sử dụng các lập luận ngữ nghĩa để
hiểu các dịch vụ tại điểm sử dụng của nó. Trong bài viết này, bạn sẽ để cho người
dùng kiểm soát việc chọn lựa loại hình dịch vụ, dữ liệu lấy về từ dịch vụ Web, và
cách trình bày dữ liệu đó.

Trước khi 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 dùng kỹ thuật
ngữ nghĩa và ứng dụng ngữ nghĩa. Đặc biệt, bài viết chỉ cho bạn cách sử dụng kỹ
thuật Web ngữ nghĩa để lấy dữ liệu từ một dịch vụ web bất kỳ và trình bày chúng
dưới dạng người dùng tự chọn.
Khi tham dự bài viết này bạn chắc chắn phải có kiến thức kỹ càng về lập trình
Java. Bạn cũng cần hiểu nhiều về khái niệm XML và khung làm việc mô tả tài
nguyên (Resource Description Framework - RDF) nói chung cũng như biết kỹ về
ngôn ngữ Web bản thể (Web Ontology Language - OWL) nói riêng. Nếu bạn cần
tìm hiểu lại ba chủ đề này hãy đọc phần 3 và 4 trong loạt hướng dẫn này.
Về loạt bài viết
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 một dịch vụ Web có gốc API
hoặc là sử dụng dữ liệu từ trang web khác lấy từ một dịch vụ Web có gốc API. 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à mashups là hiện tượng thịnh hành nhất trên
Web, từ các trang giao tiếp thông thường đến các trang tìm kiếm đặc biệt tới chiến
lượ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. Các chuỗi tiến trình diễn ra như sau:
Phần 1: Giới thiệu khái niệm mashups, 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: Giải quyết một số sự cố khi sử dụng pureXML™ của IBM® DB2 ® để
xây dựng bộ nhớ lưu trữ XML để lưu giữ kết quả của các yêu cầu trước đó và để
cho phép bạn truy lục thông tin cụ thể.
Ở cấp độ cơ bản nhất, bạn sẽ cần phải dùng bản thể luận và 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, đó là hai thành phần chính của
ngôn ngữ web bản thể (OWL), được mô tả trong Phần 4. Phần 5 Lấy các bản thể
luận 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.
Và bài viết này 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ó. Trong bài viết 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
Bài viết này là phần 6 trong loạt bài viết giải thích cách thêm các khả năng ngữ
nghĩa cho ứng dụng mashup các dịch vụ Web. Ở phần 5 (xem Tài nguyên bạn lấy
một cây thư mục đã có và bổ sung nó để cho phép người dùng dễ dàng thay đổi
dịch vụ. Trong bài viết này bạn sẽ dùng các kỹ năng ngữ nghĩa để cung cấp cho

người dùng quyền kiểm soát hoàn toàn đối với các thông tin được hiển thị và đối
với cách trình bày của nó.
Ở bài viết này bạn sẽ học cách
 Gọi một reasoner trên dữ liệu ngữ nghĩa
 Định rõ các lớp và lớp con theo lập trình
 Định rõ các đặc tính sẵn có của lớp theo lập trình
 Định rõ các giá trị đặc tính cố định theo lập trình
 Xây dựng một ứng dụng có thể lấy được thông tin dựa trên ngữ nghĩa chứ
không dựa trên các biểu thức XPath.
Trong bài viết này, bạn sẽ lấy mashup bạn tạo được từ phần 1 đến phần 5 và cho
người dùng quyền kiểm soát tối ưu. Người dùng sẽ có khả năng chọn một loại dịch
vụ, một dịch vụ Web cố định để dùng, dữ liệu lấy từ dịch vụ Web, và sự trình bày
các dữ liệu đó. Cuối cùng, bạn có thể thêm hàm mới và các dịch vụ mới vào ứng
dụng bằng cách đơn giản là thêm chúng vào bản thể luận mà không phải chạm tới
ứng dụng đó.


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 mã trong
bài viết này
 IBM® DB2® 9 (trước đây gọi là “Viper”) Cơ sở dữ liệu liên quan này bao
gồm khả năng XML mà bạn sẽ cần cho bài viết này. Bạn có thể tải về phiên
bản thử nghiệm DB2 9: DB2 Enterprise 9 hoặc DB2 Express-C 9 phiên bản
dữ liệu máy chủ DB2 Express 9 miễn phí.
 Apache Tomcat Hay dụng cụ servlet khác: bài viết này cho rằng bạn sẽ
dùng các servlet để xây dựng các ứng dụng Web, vì thế bạn sẽ cần có dụ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. 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 (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 Rational IBM™ 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 việc đó liên quan tới tài
liệu thu thập và sự triển khai của mình.

Tổng quan
Cho đến nay rất nhiều điều đã xảy ra trong loạt bài viết. Khi bạn đến điểm tột cùng
của đề án này bạn cần đảm bảo rằng bạn hiểu vị trí của mình trước khi bạn bắt đầu
để thêm vào những tính năng tiên tiến cuối cùng cho chương trình ứng dụng của
mình.
Mục đích của loạt bài viết này
Từ khởi đầu của loạt bài viết này, ý tưởng tạo ra một mashup ngữ nghĩa hoặc một
ứng dụng Web để lấy thông tin từ các nguồn khác nhau được đưa ra. Ngày nay,
mashups đã khá thông dụng. Vào thời điểm viết loạt bài này, Mashupfeed.com đã
có danh sách 994 mashups tồn tại và có thêm 2,7 mashups được đưa vào sử dụng
mỗi ngày. Nhưng mỗi một mashup đều không thay đổi loại hình thông tin chúng
trình bày. Và do đó, người dùng phải chọn một truy vấn để thực hiện, nhưng
nguồn dữ liệu và sự trình bày của nó là cố định. Ứng dụng sử dụng một dịch vụ
đơn hoặc một loạt các dịch vụ và người dùng sẽ không kiểm soát được điều xảy ra
khi chọn một truy vấn.
Mục đích của loạt bài viết này là tạo ra một chút khác biệt. Ứng dụng bạn đang
xây dựng cuối cùng sẽ mang lại cho người dùng quyền kiểm soát đối với dịch vụ,
với dữ liệu lấy được và cách trình bày các dữ liệu đó. Nhưng trước khi bước vào
nội dung chi tiết, chúng ta nên xem chúng ta đã đạt được những gì trong hành trình
này
Các bài viết trước

Ở phần một của loạt bài viết, bạn xây dựng một ứng dụng mashup cơ bản dùng để
lấy dữ liệu từ các dịch vụ bất kỳ được xác định tại một lớp Java riêng biệt. Dữ liệu
mà các dịch vụ này trình bày và hình thức trình bày được điều khiển bởi khuôn
mẫu XML lưu giữ như một đặc tính của lớp dịch vụ. Để thêm một dịch vụ mới,
bạn cần thêm một định nghĩa dịch vụ mới và mọi thứ được tiến hành tự động
Sự điều biến này thực sự có chủ ý. Nó cho phép bạn tạo ra một tình huống mà ở
đó người dùng có thể chuyển đổi các dịch vụ theo tác động. Hàm của ứng dụng có
thể thay đổi bằng cách thay đổi các nội dung của Service
Ở phần 2 bạn đã thực hiện các vấn đề về trình bày bằng việc tạo ra một tình huống
trong đó dữ liệu trước hết được lấy ra từ cơ sở dữ liệu, và nếu dữ liệu này không
tồn tại bạn sẽ phát một truy vấn và dữ liệu sẽ được bổ sung vào cơ sở dữ liệu. Sau
đó ở phần 3, và 4 bạn học về khung làm việc mô tả tài nguyên, một chi nhánh của
nó, ngôn ngữ Web bản thể (OWL).
Ở phần 5, mọi thứ nhập lại với nhau, bạn cung cấp thêm khả năng thay đổi dịch vụ
cho người dùng. Nói cách khác, nếu người dùng muốn xem kết quả từ
BarnesandNoble.com thay vì xem từ Amazon.com, người dùng phải chọn dịch vụ
đó như một lựa chọn và hệ thống sẽ hiểu cách tìm một giá trị Amazon tương
đương với cách tìm một giá trị Barnes & giá trị Noble bởi vì cả hai bộ dữ liệu đều
được mã hóa trong một bản thể luận thông thường.
Trong bài viết này bạn sẽ hiểu dần từng khái niệm này.


Các bước tiếp theo
Bây giờ là lúc tạo ra một ứng dụng mà ở đó người dùng có thể đưa ra các quyết
định của mình. Bạn không phải khởi động ứng dụng và ngay lập tức đưa ra một
hộp tìm kiếm để bạn nhập truy vấn của mình. Đầu tiên bạn phải chọn loại hình
dịch vụ như là Bookstore, MappingService, và những dịch vụ tương tự trước khi
bạn được thấy một danh mục lựa chọn các dịch vụ.
Khi bạn đã lựa chọn dịch vụ bạn sẽ được thấy một danh mục tất cả thông tin mà
bạn có thể lấy từ dịch vụ đó. Bạn sẽ có cơ hội tạo một khuôn mẫu bằng tay hoặc

một chuỗi ký tự XML/XHTML có chỗ lưu các dữ liệu hiện thời.
Từ đây bạn có thể phát một truy vấn và yêu cầu dữ liệu hiện lên theo cách bạn vừa
yêu cầu.


Bản thể luận
Hãy bắt đầu bằng việc nhớ lại các phần liên quan của bản thể luận mà bạn sẽ sử
dụng cho dự án này. (Xem ví dụ 1).

Ví dụ 1. Bản thể luận

<rdf:RDF
xmlns = "
xmlns:store = "
xml:base = "
xmlns:owl = "
xmlns:rdf = "
xmlns:rdfs= "
xmlns:xsd = "
>

<owl:Ontology rdf:about="">
<rdfs:comment>An example OWL ontology for Online
Bookstores (The
Ultimate Mashup: Part #4)</rdfs:comment>
<rdfs:label>BookStore Ontology</rdfs:label>
</owl:Ontology>

<! SERVICE DEFINITIONS >


<owl:Class rdf:ID="Service">
<rdfs:label>Web Service</rdfs:label>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#endpoint" />
<owl:minCardinality
rdf:datatype="&xsd;nonNegativeInteger">1</owl:minCardinality>

</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#rootoutputnode" />
<owl:minCardinality
rdf:datatype="&xsd;nonNegativeInteger">1</owl:minCardinality>

</owl:Restriction>
</rdfs:subClassOf>

<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#template" />
<owl:minCardinality
rdf:datatype="&xsd;nonNegativeInteger">1</owl:minCardinality>

</owl:Restriction>
</rdfs:subClassOf>

</owl:Class>
<owl:DatatypeProperty rdf:ID="endpoint">

<rdfs:domain rdf:resource="#Service"/>
<rdfs:range
rdf:resource="
</owl:DatatypeProperty>

<owl:ObjectProperty rdf:ID="inputparameter">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="#ServiceParameterMap"/>
</owl:ObjectProperty>
<owl:DatatypeProperty rdf:ID="rootoutputnode">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="xsltTransformationString">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>

<owl:DatatypeProperty rdf:ID="queryParameter">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>

<owl:DatatypeProperty rdf:ID="template">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="elementValue">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="&xsd;string"/>

</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="attributeValue">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>


<owl:Class rdf:ID="ServiceParameterMap">
<rdfs:label>Web Service Parameter Map</rdfs:label>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#paramname" />
<owl:cardinality
rdf:datatype="&xsd;nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#paramvalue" />
<owl:cardinality
rdf:datatype="&xsd;nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
<owl:DatatypeProperty rdf:ID="paramname">
<rdfs:domain rdf:resource="#ServiceParameterMap"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="paramvalue">
<rdfs:domain rdf:resource="#ServiceParameterMap"/>

<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>

<! SUBCLASSES OF SERVICE >

<owl:Class rdf:ID="Store">
<rdfs:subClassOf rdf:resource="#Service"/>
<rdfs:label>Online Store</rdfs:label>
</owl:Class>

<owl:Class rdf:ID="NewsService">
<rdfs:subClassOf rdf:resource="#Service"/>
<rdfs:label>News Service</rdfs:label>
</owl:Class>

<owl:Class rdf:ID="MappingService">
<rdfs:subClassOf rdf:resource="#Service"/>
<rdfs:label>Online Map</rdfs:label>
</owl:Class>

<owl:Class rdf:ID="Bookstore">
<rdfs:subClassOf rdf:resource="#Store"/>
<rdfs:label>Bookstore</rdfs:label>
<outputType rdf:resource="#StockItem"/>
</owl:Class>

<owl:Class rdf:ID="Videostore">
<rdfs:subClassOf rdf:resource="#Store"/>
<rdfs:label>Video Store</rdfs:label>
</owl:Class>


<! BOOKSTORE RELATED CLASSES >

<owl:Class rdf:ID="Product">
<rdfs:label>Product sold at online store</rdfs:label>
</owl:Class>

<owl:Class rdf:ID="StockItem">
</owl:Class>
<owl:DatatypeProperty rdf:ID="itemPrice">
<rdfs:label>Item Price</rdfs:label>
<rdfs:domain rdf:resource="#StockItem"/>
<rdfs:range rdf:resource="&xsd;double"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="itemDescription">
<rdfs:label>Item Description</rdfs:label>
<rdfs:domain rdf:resource="#StockItem"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="itemDetailURL">
<rdfs:label>Item Detail Page URL</rdfs:label>
<rdfs:domain rdf:resource="#StockItem"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>
<owl:ObjectProperty rdf:ID="stockedProduct">
<rdfs:label>Stocked Product</rdfs:label>
<rdfs:domain rdf:resource="#StockItem"/>
<rdfs:range rdf:resource="#Book"/>
</owl:ObjectProperty>


<owl:ObjectProperty rdf:ID="stocks">
<rdfs:domain rdf:resource="#Store"/>
<rdfs:range rdf:resource="#StockItem"/>
</owl:ObjectProperty>

<owl:Class rdf:ID="Book">
<rdfs:subClassOf rdf:resource="#Product"/>
<rdfs:label>Book</rdfs:label>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="#writtenBy" />
<owl:minCardinality
rdf:datatype="&xsd;nonNegativeInteger">1</owl:minCardinality>

</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>

<owl:DatatypeProperty rdf:ID="title">
<rdfs:label>Title</rdfs:label>
<rdfs:domain rdf:resource="#Book"/>
<rdfs:range rdf:resource="&xsd;string"/>
</owl:DatatypeProperty>


<owl:ObjectProperty rdf:ID="writtenBy">
<rdfs:label>Written By</rdfs:label>
<rdfs:domain rdf:resource="#Book"/>
<rdfs:range rdf:resource="#Author"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="writerOf">
<owl:inverseOf rdf:resource="#writtenBy"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:ID="authorOf">
<owl:equivalentProperty rdf:resource="#writerOf"/>
</owl:ObjectProperty>

<! INSTANCES >

<Bookstore rdf:ID="Amazon.com">
<endpoint>http://localhost/xml.xml</endpoint><!
>
<rootoutputnode>//Book</rootoutputnode>

<outputType>
<inputparameter rdf:resource="#amazonInput1"/>
<inputparameter rdf:resource="#amazonInput2"/>
<inputparameter rdf:resource="#amazonInput3"/>
<inputparameter rdf:resource="#amazonInput4"/>
<xsltTransformationString>

<![CDATA[

]]>
</xsltTransformationString>
<template><![CDATA[ <p><a
value='href'><value/></a> by <value/></p>
]]></template>
<elementValue>Author!itemDescription</elementValue>
<attributeValue>itemDetailURL</attributeValue>

<queryParameter>Title</queryParameter>
</Bookstore>
<ServiceParameterMap rdf:ID="amazonInput1">
<paramname>Service</paramname>
<paramvalue>AWSECommerceService</paramvalue>
</ServiceParameterMap>
<ServiceParameterMap rdf:ID="amazonInput2">
<paramname>AWSAccessKeyId</paramname>
<paramvalue>000000000000000</paramvalue>
</ServiceParameterMap>
<ServiceParameterMap rdf:ID="amazonInput3">
<paramname>SearchIndex</paramname>
<paramvalue>Books</paramvalue>
</ServiceParameterMap>
<ServiceParameterMap rdf:ID="amazonInput5">
<paramname>Title</paramname>
<paramvalue></paramvalue>
</ServiceParameterMap>
<ServiceParameterMap rdf:ID="amazonInput4">
<paramname>Operation</paramname>
<paramvalue>ItemSearch</paramvalue>
</ServiceParameterMap>

<Bookstore rdf:ID="BarnesAndNoble.com"/>
<Bookstore rdf:ID="Buy.com"/>

</rdf:RDF>

Lưu ý là dữ liệu được cung cấp cho thể hiện Amazon.com của lớp Bookstore,
nhưng không phải cho Barnesandnoble.com hay Buy.com hay các mục trong bản

thể luận của Buy.com. Bởi vì đây là một ví dụ, và cũng có thể là một chứng minh
về khái niệm. Trong một ứng dụng thực, hiển nhiên là bạn sẽ có sẵn thông tin này
hoặc là bạn sẽ nhận được báo lỗi như là NullPointerException nếu người dùng
chọn chúng. Và trong một ứng dụng thực bạn sẽ muốn bắt những loại lỗi này.
Cũng cần lưu ý rằng đặc tính outputType rất phổ biến với URI cho lớp StockItem,
vì thế ứng dụng biết nó cần xem xét điều gì.


Chuyển đổi dữ liệu thô sang dữ liệu bản thể luận
Trước khi tiếp tục bạn cần lưu ý một điểm. Ở phần 5 của loạt bài này (Xem mục
Tài nguyên bạn đã nhìn thấy việc tạo ra một chuyển đổi căn bản là chuyển dữ liệu
Amazon.com sang dữ liệu Property của riêng bạn và sau đó bằng một biến đổi đơn
giản làm cho biểu thức cần có XPath có thể quản lý được. Bài viết này cũng sẽ nói
rõ tại sao bạn sẽ không dùng XPath để phân tích các dữ liệu trả về, bạn sẽ cần
chuyển dữ liệu sang dạng bản thể luận hiện thời.
Và cũng vì đặc tính của cách mà bộ xử lý dùng trong bài viết này tương tác, bạn
cần chuyển đổi dữ liệu sang dạng bản thể luận theo cách rất đặc biệt. Bạn cần đảm
bảo rằng bản thể luận sẽ cụ thể hóa chuỗi chuyển đổi như sau. (Xem ví dụ 2):

Ví dụ 2. Chuỗi chuyển đổi


<Bookstore rdf:ID="Amazon.com">
<endpoint>http://localhost/xml.xml</endpoint><!
>
<rootoutputnode>//Book</rootoutputnode>
<outputType>
<inputparameter rdf:resource="#amazonInput1"/>
<inputparameter rdf:resource="#amazonInput2"/>
<inputparameter rdf:resource="#amazonInput3"/>

<inputparameter rdf:resource="#amazonInput4"/>
<xsltTransformationString>

<![CDATA[
<xsl:stylesheet version="1.0" xmlns=""
xmlns:store="
xmlns:xsl="
xmlns:res=" />05"
xmlns:rdf = "
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes"/>
<xsl:template match="/">
<rdf:RDF >
<xsl:apply-templates
select="/res:ItemSearchResponse/res:Items/res:Item" />
</rdf:RDF>
</xsl:template>
<xsl:template match="res:Item">
<xsl:element name="store:Author">
<xsl:attribute name="rdf:ID">_<xsl:value-of
select="res:ASIN"/><xsl:value-of
select="translate(res:ItemAttributes/res:Author, ' ', '_'
)"/></xsl:attribute>
</xsl:element>
<xsl:element name="store:Book">
<xsl:attribute name="rdf:ID">_<xsl:value-of
select="res:ASIN"/></xsl:attribute>
<xsl:element name="store:writtenBy">
<xsl:attribute name="rdf:resource">_<xsl:value-of
select="res:ASIN"/><xsl:value-of

select="translate(res:ItemAttributes/res:Author, ' ', '_'
)"/></xsl:attribute>
</xsl:element>
</xsl:element>
<xsl:element name="store:StockItem">
<xsl:attribute name="rdf:ID">AMAZON_<xsl:value-of
select="res:ASIN"/></xsl:attribute>
<xsl:element name="store:stockedProduct">
<xsl:attribute name="rdf:resource">#_<xsl:value-of
select="res:ASIN"/></xsl:attribute>
</xsl:element>
<xsl:element name="store:itemPrice">
<xsl:attribute
name="rdf:datatype"> />ribute
><xsl:value-of
select="translate(res:ItemAttributes/res:ListPrice/res:FormattedPrice, '$',
'')"/>
</xsl:element>
<xsl:element name="store:itemDetailURL">
<xsl:value-of select="res:DetailPageURL"/>
</xsl:element>
<xsl:element name="store:itemDescription">
<xsl:value-of select="res:ItemAttributes/res:Title"/>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

]]>
</xsltTransformationString>

<template><![CDATA[ <p><a
value='href'><value/></a> by <value/></p>
]]></template>
<elementValue>Author!itemDescription</elementValue>
<attributeValue>itemDetailURL</attributeValue>
<queryParameter>Title</queryParameter>
</Bookstore>


Ở đây trong ví dụ 2 này một lần nữa bạn cần tạo ra các đối tượng trong
nhưng bạn sẽ thấy nó hiện ra cụ thể.


Một số chú ý về chuyển đổi dữ liệu
Trong loạt bài này, bạn lấy dữ liệu thô và chuyển đổi nó sang dạng XML sao cho
hòa hợp với một bản thể luận cụ thể. Có thể bạn sẽ tự hỏi “Tại sao không đơn giản
là để cho reasoner tự làm ra mà không cần phải chuyển đổi dữ liệu?”. (reasoner là
một dịch vụ lấy các phát biểu có trong một bản thể luận và từ đó suy luận ra các
phát biểu mới.) Ví như bạn có thể báo cho bản thể luận biết rằng phần tử
FormattedPrice ở trong trang
không gian
tên là một equivalentProperty đối với itemPrice. Bạn có thể dùng một reasoner để
lấy dữ liệu từ kết quả thô hơn là trình bày một quá trình chuyển đổi.
Câu trả lời là không có lý do gì mà bạn không thực hiện được điều này. Nhưng sự
thật là ngày nay reasoner Web ngữ nghĩa hơi giậm giật, và cách thức này sẽ thay
đổi trọng tâm của bài viết này sang cách xây dựng bản thể luận chứ không phải
xây dựng các ứng dụng Web. Vì thế, chúng ta cần nhớ là chúng ta có quyền lựa
chọn, trong tương lai đó có thể sẽ là lựa chọn tốt cho bạn. Nhưng bây giờ, bạn sẽ
làm mọi thứ đơn giản hơn bằng trình bày việc chuyển đổi dữ liệu.
Cải tiến cấu trúc

Trước khi bạn đi sâu hơn, bạn cần phải thay đổi cấu trúc để phù hợp với hàm mới.
Thêm kiểu đầu ra
Trước khi bắt đầu, xem lại một số điều liên quan tới bản thể luận. Từ vị trí của bản
thể luận bây giờ, các lớp tương ứng sẽ như dưới đây. Trong trường hợp dịch vụ
Bookstore là một lớp con của lớp Service trả lại một hoặc nhiều StockItems thì lớp
StockItem có nhiều đặc tính như là itemPrice và stockedProduct. Nhưng một loại
dịch vụ khác NewsService chẳng hạn có thể cho ra một loại mục khác (ví dụ,
StockItem) thay vì cho ra một StockItems thì có thể cho ra một hoặc nhiều mục
NewsStory. Vì thế, để hệ thống làm việc hợp lý, bản thể luận cần phải biết rõ từng
lớp đại diện cho các mục riêng rẽ khi hiển thị câu trả lời cho dịch vụ. Để làm được
điều này, bạn cần định nghĩa đặc tính outputType cho dịch vụ (Xem ví dụ 3).

Ví dụ 3. Thêm outputType


<owl:DatatypeProperty rdf:ID="endpoint">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range

rdf:resource=" />
</owl:DatatypeProperty>

<owl:ObjectProperty rdf:ID="outputType">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="&owl;Class"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="inputparameter">
<rdfs:domain rdf:resource="#Service"/>
<rdfs:range rdf:resource="#ServiceParameterMap"/>

</owl:ObjectProperty>


Lưu ý rằng đặc tính này chứa giá trị của nó ở bất kỳ Class nào. Ví dụ ở Bookstore
giá trị của đặc tính này nằm ở StockItem. Dạng này là một dạng phức (các lớp là
các giá trị và các biểu mẫu) gây khó khăn cho việc soạn thảo một reasoner OWL.


Tạo đặc tính sẵn có
Để sử dụng được đặc tính outputType bạn cần phải truy cập được nó. Vị trí hợp lý
nhất nằm ở phương thức obtainServiceInfo() phương thức của
MashupOntologyReader để đọc thông tin đưa vào lớp Service (xem ví dụ 4).

Ví dụ 4. Tạo đặc tính sẵn có


public Service obtainServiceInfo(String
serviceURI){

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("outputType")){

l = s.getLiteral();
svc.recordExp=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()
);
}


public static void main(String[] args) {

MashupOntologyReader reader = new

×