XQueryX là dạng biểu diễn XML của XQuery. Nó được tạo bằng cách ánh xạ các luật tạo XQueryX tổng quát sang luật XML. Kết quả có thể không thuận tiện cho người đọc và viết nhưng các chương trình có thể phân tích dễ dàng, và do XQueryX biểu diễn dưới dạng XML nên có thể dựng cỏc công cụ XML chuẩn để đọc, tạo, dịch và thay đổi truy vấn.
XQueryX có thể sử dụng trong một vài môi trường:
- Sử dụng lại bộ phân tích: Trong môi trường dữ liệu không đồng nhất, một vài hệ thống cú dựng chỳng để thực hiện truy vấn. Một bộ phân tích sinh ra XQueryX cho tất cả hệ thống.
- Truy vấn trên truy vấn: Bởi vì XQueryX biểu diễn dạng XML, truy vấn có thể chuyển thành câu truy vấn mới. Ví dụ, một truy vấn có thể thực hiện trên tập các truy vấn XQueryX để xác định truy vấn nào dùng biểu thức FLWR.
- Sinh truy vấn: Trong vài môi trường lập trình hướng XML, có thệ sẽ thuận tiên hơn nếu xây dưng truy vấn dưới dạng XQueryX, do đó các công cụ XML có thể dùng để thực hiện điều này.
- Nhúng truy vấn dưới dạng XML: XQueryX có thể nhúng trực tiếp vào tài liệu XML.
2.2.4.1 Ánh xạ cú pháp
Với mỗi luật trong cú pháp tổng quát, chúng ta tạo một biểu diễn tương đương dưới dạng XML. Ví dụ, luật chứa các luật sản xuất sau:
FLWRExpr ::= (ForClause | LetClause)+ WhereClause? "return" Expr ForClause ::= "for" Variable "in" Expr ("," Variable "in" Expr)* LetClause ::= "let" Variable ":=" Expr ("," Variable ":=" Expr)*
WhereClause ::= "where" Expr
Mô hình nội dung XQueryX sau đây tương ứng với cấu trúc luật trên
<!ELEMENT forAssignment %expression;>
<!ATTLIST forAssignment variable CDATA #REQUIRED> <!ELEMENT letAssignment %expression; >
<!ATTLIST letAssignment variable CDATA #REQUIRED > <!ELEMENT where (%expression;)>
<!ELEMENT return (%expression;)> Bây giờ xét biểu thức FLWR trong XQuery
WHERE $b/publisher = "Morgan Kaufmann" AND $b/year = "1998" RETURN $b/title XQueryX tương ứng là <q:query xmlns:q="http://www.w3.org/2001/06/xqueryx"> <q:flwr> <q:forAssignment variable="$b"> <q:step axis="SLASHSLASH"> <q:function name="document"> <q:constant datatype="CHARSTRING">bib.xml</q:constant> </q:function> <q:identifier>book</q:identifier> </q:step> </q:forAssignment> <q:where> <q:function name="AND"> <q:function name="EQUALS"> <q:step axis="CHILD"> <q:variable>$b</q:variable> <q:identifier>publisher</q:identifier> </q:step>
<q:constant datatype="CHARSTRING">Morgan Kaufmann</q:constant> </q:function> <q:function name="EQUALS"> <q:step axis="CHILD"> <q:variable>$b</q:variable> <q:identifier>year</q:identifier> </q:step> <q:constant datatype="CHARSTRING">1998</q:constant> </q:function> </q:function> </q:where> <q:return> <q:step axis="CHILD"> <q:variable>$b</q:variable> <q:identifier>title</q:identifier> </q:step> </q:return> </q:flwr> </q:query> 2.2.4.2 DTD cho cú pháp XQueryX.
<!ENTITY % ORDER_LITERALS "(ASCENDING | DESCENDING)"> <!ENTITY % QUANTIFIER_TYPE "(SOME | EVERY)">
<!ENTITY % expression "(q:variable | q:constant | q:function | q:flwr | q:elementConstructor | q:predicatedExpr | q:sortBy | q:ifThenElseExpr | q:quantifier | q:exprList | q:step | q:identifier | q:nodeKindTest)">
<!ENTITY % AXIS_TYPE "(DEREFERENCE | ANCESTOR | ANCESTORORSELF
| ATTRIBUTE | CHILD | DESCENDANT | DESCENDANTORSELF | FOLLOWING
| FOLLOWINGSIBILING | NAMESPACE | PARENT | PRECEDING | PRECEDINGSIBLING | SLASHSLASH | SELF)">
<!ENTITY % NODE_KIND "(NODE | TEXT | COMMENT | DATA | PROCESSING_INSTRUCTION)">
<!ELEMENT q:query (q:functionDefinition* , %expression;)>
<!ELEMENT q:functionDefinition (q:argumentDeclaration* , %expression;)> <!ATTLIST q:functionDefinition functionName CDATA #REQUIRED datatype CDATA #REQUIRED >
<!ELEMENT q:argumentDeclaration EMPTY>
<!ATTLIST q:argumentDeclaration name CDATA #REQUIRED datatype CDATA #REQUIRED >
<!ELEMENT q:exprList (%expression;)*>
<!ELEMENT q:predicatedExpr (%expression; , q:predicate+)>
<!ELEMENT q:predicate ((q:rangeFrom , q:rangeTo) | %expression;)> <!ELEMENT q:rangeFrom (%expression;)>
<!ELEMENT q:rangeTo (%expression;)> <!ELEMENT q:variable (#PCDATA)> <!ELEMENT q:identifier (#PCDATA)> <!ELEMENT q:constant (#PCDATA)>
<!ATTLIST q:constant datatype CDATA #IMPLIED > <!ELEMENT q:function (%expression;)*>
<!ATTLIST q:function name CDATA #REQUIRED >
<!ELEMENT q:flwr ((q:forAssignment | q:letAssignment)+ , q:where? , q:return)>
<!ELEMENT q:forAssignment %expression;>
<!ATTLIST q:forAssignment variable CDATA #REQUIRED > <!ELEMENT q:letAssignment %expression;>
<!ATTLIST q:letAssignment variable CDATA #REQUIRED > <!ELEMENT q:where (%expression;)>
<!ELEMENT q:return (%expression;)>
<!ELEMENT q:ifThenElseExpr (%expression; , %expression; , %expression;)> <!ELEMENT q:sortBy (%expression; , q:sortfield+)>
<!ELEMENT q:sortfield (%expression;)>
<!ATTLIST q:sortfield order %ORDER_LITERALS; "ASCENDING" > <!ELEMENT q:quantifier (q:quantifierAssignment , %expression;)>
<!ATTLIST q:quantifier type %QUANTIFIER_TYPE; "SOME" > <!ELEMENT q:quantifierAssignment (%expression;)>
<!ATTLIST q:quantifierAssignment variable CDATA #REQUIRED >
<!ELEMENT q:elementConstructor (q:tagName , q:attributeConstructor* , (%expression;)*)>
<!ELEMENT q:tagName (q:identifier | q:variable)>
<!ELEMENT q:attributeConstructor (q:attributeName , q:attributeValue)> <!ELEMENT q:attributeName (q:identifier | q:variable)>
<!ELEMENT q:attributeValue (%expression;)> <!ELEMENT q:step (%expression; , %expression;)> <!ATTLIST q:step axis %AXIS_TYPE; #REQUIRED abbreviated (true | false ) 'true' >
<!ELEMENT q:dot EMPTY> <!ELEMENT q:dotdot EMPTY>
<!ELEMENT q:nodeKindTest (q:piTargetTest?)>
<!ATTLIST q:nodeKindTest kind %NODE_KIND; #REQUIRED > <!ELEMENT q:piTargetTest (#PCDATA)>
Wrapper mà chúng tôi xây dựng dùng ngôn ngữ DEL làm ngôn ngữ biểu diễn kịch bản trích chọn thông tin. DEL là được tổ chức W3C công bố. Nó đó được sử dụng trong dự án Republica. Một ưu điểm của DEL là có thể dùng để trích chọn dữ liệu cả tài liệu HTML hay một tài liệu văn bản thông thường. Cũng chính vì thế mà nó khụng tận dụng được hết các cấu trúc của HTML. Tuy nhiên do được biểu diễn đưới dạng XML nên dễ dàng phân tích và xây dựng. Để áp dụng vào việc xây dựng wrapper chúng tôi đã bỏ bớt một số phần của DEL (hỗ trợ để tách văn bản) cũng như thêm một số phần tử để việc tách hiệu quả hơn.
2.3.1 Các ngôn ngữ kịch bản tách dữ liệu trong wrapper
Nhiều wrapper cung cấp một ngôn ngữ để mô tả các luật tách để tách dữ liệu từ các tài liệu HTML. Các ngôn ngữ này dùng để thể hiện các truy vấn trong quá trình tỏch. Nó cú cac thuộc tính đặc biệt sau: (a) tỏch cỏc cấu trúc cú pháp từ tài liệu HTML; (b) xác định cấu trúc đó dựa vào nội dung của nó (ngữ nghĩa); (c) duyệt theo cấu trúc dựa theo biểu thức đường dẫn; và (d) ánh xạ các cấu trúc đó tới cấu trúc đối tượng tương ứng của kết quả.
HEL (HTML Extraction Language) là ngôn ngữ tách dữ liệu sử dụng trong dự án W4F. HEL là ngôn ngữ dạng DOM trong đó tài liệu HTML được biểu diễn dưới dạng đồ thị các thẻ.
Ví dụ một luật tách của HEL: caption = html.body.table[0].tr[*].txt
HEL mô hình tài liệu HTML theo mô hình DOM và xác định thông tin tách dựa vào cấu trúc phân lớp của cây. Dữ liệu tách ra theo các luật lưu vào các trường có trong lược đồ ban đầu dạng danh sách. Thông tin sau đó được lưu theo NSL (nested string lists). Cuối cùng cấu trúc NSL được ánh xạ theo cấu trúc trong wrapper. W4F cung cấp các hàm để các chương trình sử dụng thông tin tách trong trình.
Dự án AraneusWTK sử dụng ngôn ngữ NF để biểu diễn các luật tỏch. Cỏc luật tách trong AraneusWTK biểu diễn theo cú pháp BNF.
Ví dụ
$ConfWithInitial:
<h3> // see X,Y,Z
<a[ ]name="[a-z]">$Initial</a>(,<a[ ]name="[a-z]">[A-Z]</a>)* </h3>
( <ul>
(<li><a[ ]href="$ConfURL">$Acronym</a> $TmpConfName { $ConfName.replaceAll("[(]*[)]",""); } $TP1 )* </ul> )? ; $Initial: [A-Z]; $TmpConfName: - (\s)? $ConfName; EXCEPTION() { $ConfName.reset();
$Acronym.cutAll(); // Append $Acronym .. $ConfName.paste();
$TmpConfName.cutAll(); // ... and $TmpConfName documents... $ConfName.put(" "); // ... separated by a space...
$ConfName.paste(); // ... to form $ConfName } $TP1: [ $Initial char(1), $Acronym char(100), $ConfName char(255), $ConfURL char(255)
] END
Trong quá trình đối sỏnh cỏc luật NF dữ liệu có thể được tách ra theo một trong các cấu trúc khai báo trong các $TPi (i là số nguyên). $TPi khai báo một cấu trúc đơn giản bao gồm tờn cỏc trường dữ liệu ra và kiểu dữ liệu. Ngoài ra NF còn cung cấp một cơ chế bắt lỗi.
Nói chung nhiều dự án xây dựng wrapper đều sử dụng một ngôn ngữ nào đó. Dự án Jedi dùng ngôn ngữ Jedi, Lapis dựng cỏc ràng buộc văn bản (text contrain) và nhiều dự án dùng biểu thức chính quy làm ngôn ngữ kịch bản.
Trong các ngôn ngữ trên dữ liệu ra có cấu trúc khá đơn giản (Araneus dùng cấu trúc danh sách, còn HEL dựa vào cấu trúc NSL để chương trình sử dụng chúng định dạng lại). Nó không thể đưa ra được một kết quả có cấu trúc phức tạp.
Trong dự án này chúng tôi đã chọn ngôn ngữ DEL làm ngôn ngữ kịch bản. Cấu trúc dữ liệu ra rất linh hoạt nó được biểu diễn ngay trong quỏ tỡnh tỏch thông tin. Một lý do nữa mà chúng tôi chọn DEL đó là DEL là một ngôn ngữ có định dạng XML. Do đó không phải mất công xây dựng một chương trình phân tích cú pháp phức tạp mà có thể sử dụng ngay các công cụ phân tích XML để phân tích chúng.
2.3.2 Giới thiệu DEL
DEL là tài liệu dạng XML mô tả quá trình chuyển từ một định dạng dữ liệu khác sang dạng XML. Một kịch bản DEL cho biết cách xác định vị trí và tỏch cỏc đoạn dữ liệu từ một dữ liệu vào và chốn chỳng vào một tài liệu XML kết quả. Một bộ xử lý tài liệu DEL có thể dùng để trích thông tin rồi tạo một tàI liệu XML mới hay thay đổi tàI liệu XML hiện tại bằng cách thờm cỏc phần tử mới và các thuộc tích ở một phần tử xác định bằng biểu thức XPath. Định vị các đoạn dữ liệu
trên dữ liệu vào có thể thực hiện bằng cách tìm kiếm theo mẫu và đối sánh theo biểu thức chính quy. Các đoạn dữ liệu trích được trước hết được lưu vào các thanh ghi (hay ngăn xếp) để có thể lọc lại trước khi đưa ra. Dữ liệu sau đó được từ các thanh ghi( hay ngăn xếp) và đặt vào vị trí chính xác trong cây DOM của tàI liệu XML sinh ra. Để đặt dữ liệu vào XML, một con trỏ vị trí được dùng để lưu vị trí hiện hành. Con trỏ vị trí có thể thay đổi bằng biểu thức XPath.
2.3.3 Định nghĩa ngôn ngữ trích dữ liệu
Phần sau đây sẽ mô tả các phần tử của ngôn ngữ trích chọn dữ liệu, các thuộc tính cũng như giá trị của nó.
Chú ý: Giá trị của các thuộc tính “stack” và “regX”(trong đó X là tên thanh ghi do người dùng định nghĩa có ít nhất một ký tự) sẽ được phân tích thành giá trị trước khi sử dụng. Sau đó giá trị thực sự chủa chúng sẽ được lấy từ bộ nhớ (stack hay register). Trong các trường hợp khác giá trị thực sự được cho trong giá trị của thuộc tính.
2.3.3.1 wrapper
Chức năng: phần tử wrapper là phần tử chứa ( phần tử gốc) cho các luật kịch bản DEL. Khi tạo một tàI liệu ra mới, phần tử map đầu tiên có thuộc tính maptype là “createDocument”.
Chứa: đầu tiên là các phần tử template và map sau đó có thể có một trong các phần tử sau đây: repeat, map, extract, test, set hay runtemplate.
Thuộc tính: không có Cú pháp:
<wrapper> </wrapper>
2.3.3.2 url
Chứa: Không
Thuộc tính: fetch (bắt buộc) cách lấy trang web về, để tăng hiệu năng chúng tôi cung cấp một số cơ chế để khác nhau để thực hiện điều này. timeout: thời gian giới hạn để lấy trang web.
Giá trị của fetch:
- sequence: lấy trang web theo một trong hai cơ chế khác nhau S ? T nếu cớ chế thứ nhất lỗi thì lấy theo cớ chế thứ hai
- execution: lấy trang web theo trong hai cơ chế đồng thời S | T có một cớ chế thành công thì sẽ kết thúc
2.3.3.3 nextpage
Chức năng: Liên kết đến trang web tiếp theo trong quá trình tách dữ liệu. Giá trị của nó là một siêu liên kết. Rất nhiều các web site lưu thông tin trên nhiều trang mà để lấy đầy đủ thông tin đòi hỏi phải duyệt hết các trang.
Chứa : Không
2.3.3.4 template
Chức năng: phần tử template được dùng để như phần tử chứa cỏc dãy cỏc phần tử hay dùng. Phần tử runtemplate sẽ được dùng để gọi nộii dung các phần tử template Chứa: Có thể chứa một trong các phần tử sau đây: repeat, map, extract, test, set hay runtemplate.
Thuộc tính: name(bắt buộc) Cú pháp: <template name="attribute_value"> </template> Ví dụ: <template name="MakeDate"> </template> 2.3.3.5 repeat
Chức năng: phần tử repeat lập lại nội dung của nó, tức là nội dung các phần tử dưới nó.
Chứa: Có thể chứa một trong các phần tử sau đây: repeat, map, extract, test, set hay runtemplate.
Thuộc tính: times(bắt buộc) Thuộc tính times:
. Khi thuộc tính times là “*”, nó lặp lại nội dung của nó cho tới khi một trong các phần tử extract thiết lập trạng tháI “dataStreamError”.
.Khi thuộc tính times là một số (ví dụ “8”), nó lặp lại nội dung của nó đúng số đó lần hay tới khi một trong các phần tử extract thiết lập trạng tháI “dataStreamError”.
Chú ý: trong vòng repeat, khi cố gắng trích dữ liệu nhưng không tìm thấy (biểu thức đang tìm , bộ phân tích DEL sẽ thiết lập trạng tháI “dataStreamError” để dừng vòng lặp. Trong trường hợp trạng tháI “dataStreamError” được thiết lập ngoàI vòng lặp, cả quá trình wrapping dừng lại.
Cú pháp: <repeat times="attribute_value"> </repeat> <repeat times="*"> </repeat> 2.3.3.6 map
Chức năng: phần tử map chèn nội dung vào nút XMl của tàI liệu ra. Nó chuyển cont trỏ trong tàI liệu XML ra để xác định vị trí điểm chèn cho nỳt. Nó cũng lưu phần tử hiện hành.
Chứa: Không có
Thuộc tính: Các thuộc tính và các giá trị có thể:
. maptype(bắt buộc): cho bộ phân tích DEL biết cách và vị trí trong tài liệu XML (xác định bởi thuộc tính nút) để chèn nội dung.
- “createDocument”: Tạo một tài liệu XML mới và xác định phần tử gốc. Phần tử gốc lấy tên từ giá trị của nút (biểu thức XPath). Sau lệnh này, con trỏ chuyển tới phần tử gốc này.
- “createElement”: Tạo phần tử mới trong tàI liệu XML. Phần tử mới là phần tử con cuối cùng trong các phần tử con của phần tử hiện hành. Tên của phần tử là giá trị của thuộc tính. Khi nội dung của truộc tính được xác định, một nút văn bản sẽ được tạo ra bên trong phân tử mới chứa giá trị đã phân tích của nội dung phần tử. Sau lệnh này, con trỏ chuyển tới phần tử mới.
- “createElelmentBefore”: Làm việc như “createElement” nhưng tạo phần tử mới trước phần tử hiện hành trở bởi con trỏ (ở cùng mức)
- “createElelmentAfter”: Làm việc như “createElement” nhưng tạo phần tử mới sau phần tử hiện hành trở bởi con trỏ (ở cùng mức) - “createAttribute”: Tạo một thuộc tính trong tàI liệu XML. Thuộc
tính được tạo cho phần tử mà con trỏ đang chỉ. Nội dung của thuộc tính là giá trị đã phân tích của nội dung thuộc tính. Nừu thuộc tính đã tồn tại thì giá trị cũ của nó sẽ bị ghi đè.
- “createTextNode”: Thêm một nút văn bản vào tại liệu XML. Nút văn bản được thêm vào nút cuối cùng của phần tử trong đó con trỏ đang định vị. Nội dung của nút văn bản là giá trị đã phân tích của nội dung thuộc tính.
- “createCDATA”: Thêm phần CDATA vào tài liệu XML. Phần này được thêm vào phần tử hiện hành. Nội dung của phần CDATA là giá trị đã phân tích của nội dung thuộc tính.
- “createProcessingInstruction”: Thêm chỉ thị xử lý vào tài liệu XML. Phần này được thêm vào trước phần tử hiện hành. Nội dung của chỉ thị xử lý là giá trị đã phân tích của nội dung thuộc tính.
- “moveCursor”: Di chuyển con trỏ tới phần tử đã được tạo trong tài liệu XML. Vị trí của con trỏ được xác định trong thuộc tính nhu một biểu thức XPath. Nếu biểu thức XPath chỉ tới nhiều nỳt thỡ nỳt cuối cùng sẽ được chọn.
- “documentReady”: Cắt dữ liệu nguồn thành các phần để cho phép xử lý hiệu quả hơn. Sinh ra một cây DOM trong bộ nhớ. - “getTemplate”: Nạp một mấu XML kết quả như một khung cho
từng phần tử một hay dùng để ấn định nọi dung của một số nút XML nếu cần thiết.
. node(bắt buộc, sẽ được phân tích): Xác định vị trí con trỏ trong tài liệu XML ra theo biểu thức XPath.
.content(tuỳ chọn, sẽ được phân tích): Đưa ra nội dung của, ví dụ các thuộc tính trong tài liệu XML.
.value(bắt buộc với “getTemplate”): Sinh ra phần tử gốc tài liệu XML. Cú pháp:
<map maptype="attribute_value" node="attribute_value" content="value"/> Ví dụ:
<map maptype="createDocument" node="root"/>
2.3.3.7 extract
Chức năng: phần tử extract lấy dữ liệu từ dữ liệu nguồn.
Chứa: Có thể chứa một trong các phần tử sau đây: repeat, map, extract, test, set hay runtemplate.
Thuộc tính: exptype(bắt buộc), expression(bắt buộc, sẽ được phân tích), save(tuỳ chọn, sẽ được phần tích).
.exptype: cho bộ phân tích DEL biết phần dữ liệu nào sẽ được tách và lưu ở đâu.
.expression xác định exptype. Các giá trị của exptype: - “length”: Tách length ký tự từ đầu.
- “upto”: Tách dữ liệu cho tới khi tới nội dung của thuộc tính expression.
- “over”: Tách phần dữ liệu nguồn chứa trong thuộc tính expression.
- “re_upto”:Tỏch dữ liệu cho tới khi tài liệu nguồn chứa phần khớp với nội dung biểu thức của thuộc tính expression.
- “re_over”: Tách dữ liệu chứa trong dữ liệu nguồn chứa phần khớp với nội dung biểu thức của thuộc tính expression.
- “content”: Tách phần dữ liệu nguồn có chứa biểu thức chính quy