Các hàm API XPath của Java

Tóm tắt:

Viết các biểu thức XPath dễ hơn rất nhiều nhiều so với việc viết mã chuyển hướng

Mô hình đối tượng tài liệu (Document Object Model -DOM) chi tiết. Khi bạn cần

rút trích thông tin từ tài liệu XML thì cách nhanh nhất và đơn giản nhất là nhúng

biểu thức XPath vào bên trong chương trình Java™. Java 5 giới thiệu gói

java.xml.xpath, một thư viện độc lập mô hình đối tượng XML dùng để truy vấn

các tài liệu XML với XPath.

27/06/2007 - Từ các góp ý của người đọc, tác giả đã cập nhật các biểu thức XPath

đã được biên dịch (tham khảo phần mã ngắn ở Ví dụ 3).

25/08/2008 - Từ cácgóp ý của người đọc, tác giả đã thay

"www.example.org/books" thành "www.example.com/books" trong Ví

dụ 6, không gian tên (namespace)được đề cập đến trong đoạn văn trước Ví dụ 9,

và Ví dụ 9.

pdf21 trang | Chuyên mục: Java | Chia sẻ: dkS00TYs | Lượt xem: 2231 | Lượt tải: 1download
Tóm tắt nội dung Các hàm API XPath của Java, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
g gì được trả lại chính 
xác tùy thuộc vào kết quả trong biểu thức XPath và kiểu của đối tượng cũng tương 
ứng với kiểu các bạn đưa ra. 
 Kiểu số tương ứng với gói java.lang.Double 
 Kiểu chuỗi ký tự tương ứng với gói java.lang.String 
 Kiểu logic tương ứng với gói java.lang.Boolean 
 Kiểu tập hợp nút tương ứng với gói org.w3c.dom.NodeList 
XPath 2 
Giả sử bạn đang làm việc với XPath 1.0. XPath 2 cho phép mở rộng và sử dụng lại 
kiểu hệ thống cơ bản. Sự thay đổi chính trong Java XPath API cho phép hỗ trợ 
XPath 2 thêm vào một số kiểu dữ liệu mới của XPath. 
Khi bạn thực hiện đánh giá biểu thức XPath trong Java, tham biến thứ hai xác định 
kiểu trả lại mà bạn muốn. Có năm khả năng có thể và tất cả các hằng số đều lưu 
nằm trong lớp javax.xml.xpath.XPathConstants: 
 XPathConstants.NODESET 
 XPathConstants.BOOLEAN 
 XPathConstants.NUMBER 
 XPathConstants.STRING 
 XPathConstants.NODE 
Trường hợp cuối cùng XPathConstants.NODE không thực sự phù hợp trong kiểu 
của XPath. Bạn sử dụng nó khi bạn biết chính xác biểu thức XPath sẽ chỉ trả lại 
một nút hoặc bạn không muốn có nhiều hơn một nút kết quả. Nếu biểu thức XPath 
trả lại nhiều hơn một nút thì bạn phải xác định bằng cách sử dụng 
XPathConstants.NODE, sau đó dùng phương thức evaluate() trả lại nút đầu tiên 
trong tài liệu cho phép. Nếu biểu thức XPath lựa chọn một tập hợp rỗng và bạn sử 
dụng XPathConstants.NODE thì phương thức evaluate() trả lại giá trị rỗng. 
Nếu chuyển đổi theo yêu cầu không được thực hiện thì phương thức evaluate() bắt 
được ngoại lệ XPathException. 
Các ngữ cảnh không gian tên (Namespace contexts) 
Nếu các phần tử trong tài liệu nằm trong một không gian tên thì biểu thức XPath 
cho truy vấn khi thực hiện thì phải sử dụng đúng không gian tên. Biểu thức XPath 
không cần sử dụng các tiền tố giống nhau mà chỉ cần sử dụng các không gian tên 
URI giống nhau. Vì vậy, khi tài liệu XML sử dụng không gian tên mặc định thì 
biểu thức XPath phải sử dụng tiền tố mặc dù mục tiêu tài liệu không sử dụng nó. 
Tuy nhiên, Chương trình Java không phải là một tài liệu XML nên giải pháp 
không gian tên thông thường không áp dụng. Thay vì bạn cung cấp đối tượng 
tương ứng với các dạng tiền tố tới các không gian tên URI. Đối tượng này là ví dụ 
của giao diện javax.xml.namespace.NamespaceContext. Ví dụ, giả sử tài liệu về 
các quyển sách được lưu trong không gian tên  có 
dạng như trong Ví dụ 5: 
Ví dụ 5. Tài liệu XML sử dụng không gian tên mặc định 
 Snow Crash 
 Neal Stephenson 
 Spectra 
 0553380958 
 14.95 
Biểu thức XPath thực hiện tìm kiếm các tiêu đề của tất cả các quyển sách của tác 
giả Neal Staphenson có dạng như sau //pre:book[pre:author="Neal 
Stephenson"]/pre:title/text(). Tuy nhiên, bạn phải xác định thêm tiền tố pre tới địa 
chỉ URI  Nhưng điều này có chút rắc rối đó là 
giao diện NamespaceContext không phải là giao diện thực thi mặc định trong bộ 
công cụ phát triển phần mềm Java (JDK) hoặc JAXP, nhưng điều đó không quan 
trọng lắm. Tuy nhiên, vấn đề này rất là khó để để thực thi theo yêu cầu của chính 
bạn. Ví dụ 6 mô phỏng một thực thi đơn giản cho một không gian tên xác định. 
Bạn nên xác định tương ứng thêm tiền tố xml để rõ ràng hơn. 
Ví dụ 6. Một ngữ cảnh đơn giản để thực hiện buộc một không gian tên cùng 
với giá trị mặc định 
import java.util.Iterator; 
import javax.xml.*; 
import javax.xml.namespace.NamespaceContext; 
public class PersonalNamespaceContext implements NamespaceContext { 
 public String getNamespaceURI(String prefix) { 
 if (prefix == null) throw new NullPointerException("Null prefix"); 
 else if ("pre".equals(prefix)) return ""; 
 else if ("xml".equals(prefix)) return XMLConstants.XML_NS_URI; 
 return XMLConstants.NULL_NS_URI; 
 } 
 // This method isn't necessary for XPath processing. 
 public String getPrefix(String uri) { 
 throw new UnsupportedOperationException(); 
 } 
 // This method isn't necessary for XPath processing either. 
 public Iterator getPrefixes(String uri) { 
 throw new UnsupportedOperationException(); 
 } 
} 
Thật không khó để sử dụng một ánh xạ để thực hiện lưu trữ các thông tin đã được 
gắn vào và thêm vào các phương thức khởi tạo để cho phép sử dụng dụng lại nhiều 
hơn ngữ cảnh không gian tên. 
Sau khi bạn tạo ra đối tượng NamespaceContext thay vì vậy cài đặt trên đối tượng 
XPath trước khi thực hiện biên dịch biểu thức. Từ thời điểm này trở đi bạn có có 
thể thực hiện truy vấn bằng cách sử dụng những dạng tiền tố này phía trước. Ví 
dụ: 
Ví dụ 7. Truy vấn XPath sử dụng các không gian tên 
 XPathFactory factory = XPathFactory.newInstance(); 
 XPath xpath = factory.newXPath(); 
 xpath.setNamespaceContext(new PersonalNamespaceContext()); 
 XPathExpression expr 
 = xpath.compile("//pre:book[pre:author='Neal Stephenson']/pre:title/text()"); 
 Object result = expr.evaluate(doc, XPathConstants.NODESET); 
 NodeList nodes = (NodeList) result; 
 for (int i = 0; i < nodes.getLength(); i++) { 
 System.out.println(nodes.item(i).getNodeValue()); 
 } 
Các trình phân tích hàm 
Trong một số trường hợp, nó rất hiệu quả khi định nghĩa các hàm mở rộng trong 
ngôn ngữ Java để sử dụng trong các biểu thức XPath. Các hàm này thực hiện các 
nhiệm vụ khó mà không thể thực hiện bằng XPath thuần túy. Tuy nhiên, các hàm 
theo nghĩa nên đúng là các hàm vì vậy các hàm này không thể là các phương thức 
đơn giản được. (Các hàm XPath có thể được đánh giá theo nhiều cách và nhiều 
thời điểm khác nhau.) 
Các hàm mở rộng thực hiện truy cập thông qua Java XPath API phải thực thi được 
giao diện javax.xml.xpath.XPathFunction. Giao diện này khai báo một phương 
thức dánh giá đơn giản: 
public Object evaluate(List args) throws XPathFunctionException 
Phương thức này nên trả lại một trong năm kiểu giá trị mà ngôn ngữ Java để có thể 
chuyển đổi được sang XPath: 
 String 
 Double 
 Boolean 
 Nodelist 
 Node 
Cụ thể, Ví dụ 8 hiển thị hàm mở rộng để xác định giá trị kiểm tra trong ISBN và 
trả lại kết quả có kiểu Boolean. Nguyên tắc cơ bản của kiểm tra tổng này là một 
trong chín số đầu tiên được nhân bởi vị trí của nó (đó là, số đầu chỉ lần một, số thứ 
hai chỉ lần hai, và ...). Các giá trị này được thêm vào và được nhắc lại sau khi thực 
hiện chia cho 11 để có được kết quả. Nếu số còn lại là mười thì số cuối cùng được 
xác định là X 
Ví dụ 8. Hàm mở rộng XPath dành cho việc kiểm tra ISBNs 
import java.util.List; 
import javax.xml.xpath.*; 
import org.w3c.dom.*; 
public class ISBNValidator implements XPathFunction { 
 // This class could easily be implemented as a Singleton. 
 public Object evaluate(List args) throws XPathFunctionException { 
 if (args.size() != 1) { 
 throw new XPathFunctionException("Wrong number of arguments to valid-
isbn()"); 
 } 
 String isbn; 
 Object o = args.get(0); 
 // perform conversions 
 if (o instanceof String) isbn = (String) args.get(0); 
 else if (o instanceof Boolean) isbn = o.toString(); 
 else if (o instanceof Double) isbn = o.toString(); 
 else if (o instanceof NodeList) { 
 NodeList list = (NodeList) o; 
 Node node = list.item(0); 
 // getTextContent is available in Java 5 and DOM 3. 
 // In Java 1.4 and DOM 2, you'd need to recursively 
 // accumulate the content. 
 isbn= node.getTextContent(); 
 } 
 else { 
 throw new XPathFunctionException("Could not convert argument type"); 
 } 
 char[] data = isbn.toCharArray(); 
 if (data.length != 10) return Boolean.FALSE; 
 int checksum = 0; 
 for (int i = 0; i < 9; i++) { 
 checksum += (i+1) * (data[i]-'0'); 
 } 
 int checkdigit = checksum % 11; 
 if (checkdigit + '0' == data[9] || (data[9] == 'X' && checkdigit == 10)) { 
 return Boolean.TRUE; 
 } 
 return Boolean.FALSE; 
 } 
} 
Bước tiếp theo là tạo ra hàm mở rộng được hỗ trợ chương trình Java. Để làm điều 
này bạn cài đặt javax.xml.xpath.XPathFunctionResolver trong đối tượng XPath 
trước khi tiến hành biên dịch biểu thực. Trình phân tích hàm thực hiện ánh xạ tên 
XPath và không gian tên URI cho hàm tới lớp Java thực thi hàm đó. Ví dụ 9 là 
trình phân tích hàm đơn giản cho phép ánh xạ hàm biểu thức valid-isbn với không 
gian tên  tới lớp trong Ví dụ 8. Ví dụ, biểu thức 
XPath //book[not(pre:valid-isbn(isbn))] thực hiện tìm tất cả các quyển sách có 
kiểm tra ISBN không phù hợp với quy định. 
Ví dụ 9. Chức năng ngữ cảnh công nhận hàm mở rộng valid-isbn 
import javax.xml.namespace.QName; 
import javax.xml.xpath.*; 
public class ISBNFunctionContext implements XPathFunctionResolver { 
 private static final QName name 
 = new QName("", "valid-isbn"); 
 public XPathFunction resolveFunction(QName name, int arity) { 
 if (name.equals(ISBNFunctionContext.name) && arity == 1) { 
 return new ISBNValidator(); 
 } 
 return null; 
 } 
} 
Bởi vì các hàm mở rộng phải đặt trong các không gian tên nên bạn phải sử dụng 
NamespaceResolver khi tiến hành đánh giá biểu thức chứa các hàm mở rộng, nếu 
tài liệu đang được thực hiện truy vấn thì không được sử dụng không gian tên. Bởi 
vì XPathFunctionResolver, XPathFunction, và NamespaceResolver là các giao 
diện,nếu thuận tiện bạn có thể đặt chúng ngang hàng nhau cùng vào một lớp. 
Kết luận 
Nhận thấy rằng việc viết các câu truy vấn bằng các ngôn ngữ khai báo như SQL và 
XPath là dễ dàng hơn nhiều so với việc viết các câu truy vấn này trong các ngôn 
ngữ mệnh lệnh như Java và C. Đồng thời ngược lại thực hiện viết các cấu trúc 
logic phức tạp trong ngôn ngữ kiểu máy Turing như Java và C lại dễ dàng hơn 
nhiều so với việc viết trong các ngôn ngữ khai báo như SQL và XPath. Nhưng thật 
may ta có thể kết hợp trộn cả hai lại với nhau cho phép sử dụng các API dưới dạng 
như Java Database Connectivity (JDBC) và javax.xml.xpath. Khi mà phần lớn dữ 
liệu trên thế giới được hướng chuyển sang XML thì javax.xml.xpath sẽ trở thành 
quan trọng như là java.sql. 
Mục lục 
 XPath 
 Một ví dụ đơn giản 
 Các ngữ cảnh không gian tên (Namespace contexts) 
 Các trình phân tích hàm 
 Kết luận 

File đính kèm:

  • pdfCác hàm API XPath của Java.pdf
Tài liệu liên quan