Sử dụng đối tượng NamespaceContext của ngôn ngữ Java với XPath Các phương thức để phân tích các không gian tên với API của Java pdf

28 262 0
Sử dụng đối tượng NamespaceContext của ngôn ngữ Java với XPath Các phương thức để phân tích các không gian tên với API của Java pdf

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Sử dụng đối tượng NamespaceContext của ngôn ngữ Java với XPath Các phương thức để phân tích các không gian tên với API của Java Holger Kraus, Chuyên gia IT, IBM Tóm tắt: Nếu bạn muốn dùng các không gian tên trong các biểu thức XPath, bạn phải cung cấp đường dẫn của tiền tố được sử dụng cho URI của không gian tên. Bài viết này mô tả ba biến thể của việc cung cấp tiền tố cho ánh xạ không gian tên. Bài này có các đoạn mã mẫu giúp bạn dễ dàng viết mã cho NamespaceContext. Điều kiện tiên quyết và ví dụ Trong bài này, tôi giả sử rằng bạn đã quen với các chi tiết kỹ thuật được mô tả trong "Đánh giá XPath từ nền tảng Java™" do Brett McLaughlin viết. Nếu bạn chưa biết cách thực thi các chương trình Java sử dụng XPath, xin vui lòng tham khảo bài viết của Brett (tìm thấy ở Tài nguyên.) Và bạn cũng đã biết các hàm API cần thiết để đọc tệp XML và để đánh giá biểu thức XPath. Bạn sẽ dùng tệp XML sau cho tất cả các ví dụ trong bài: Ví dụ 1. Tệp XML mẫu <?xml version="1.0" encoding="UTF-8"?> <books:booklist xmlns:books="http://univNaSpResolver/booklist" xmlns="http://univNaSpResolver/book" xmlns:fiction="http://univNaSpResolver/fictionbook"> <science:book xmlns:science="http://univNaSpResolver/sciencebook"> <title>Learning XPath</title> <author>Michael Schmidt</author> </science:book> <fiction:book> <title>Faust I</title> <author>Johann Wolfgang von Goethe</author> </fiction:book> <fiction:book> <title>Faust II</title> <author>Johann Wolfgang von Goethe</author> </fiction:book> </books:booklist> Mẫu XML này có ba không gian tên (namespace) được khai báo trong thành phần gốc và một cái được khái báo trong thành phần con. Bạn sẽ thấy sự khác biệt từ ví dụ này. Các từ viết tắt hay dùng  API: Giao diện lập trình ứng dụng  DOM: Mô hình đối tượng tài liệu  URI: Định danh tài nguyên tổng quát  XHTML: Ngôn ngữ đánh dấu siêu văn bản mở rộng  XML: Ngôn ngữ đánh dấu mở rộng  XSD: Định nghĩa lược đồ XML  XSLT: Chuyển đổi ngôn ngữ định kiểu mở rộng Điều thú vị thứ hai về XML mẫu này là thành phần booklist có ba thành phần con, tất cả có tên là book. Nhưng thành phần con đầu tiên có không gian tên là science, trong khi thành phần con khác có không gian tên là fiction. Điều này có nghĩa là, những thành phần này là khác nhau đối với XPath. Bạn sẽ thấy các hệ quả trong các ví dụ tiếp theo. Cũng cần phải nói trước, đoạn mã không được tối ưu hóa cho việc bảo trì nhưng nó dễ đọc. Có nghĩa là nó có một số chỗ dư thừa. Kết quả được đưa ra bằng cách đơn giản nhất thông qua System.out.println(). Tất cả các dòng của đoạn mã liên quan đến kết quả được viết tắt với ' ' trong bài viết. Tôi cũng không đề cập đến phương thức trợ giúp (helper) trong bài này, nhưng chúng đi kèm trong tệp tải về (Xem Tải về). Nền tảng lý thuyết Ý nghĩa của các không gian tên là gì và tại sao phải quan tâm tới chúng? Một không gian tên là một phần của định danh cho một thành phần hay thuộc tính. Bạn có thể có các thành phần hoặc thuộc tính với cùng tên cục bộ, nhưng khác không gian tên. Chúng khác nhau hoàn toàn. Xem ví dụ ở trên (science:book và fiction:book). Bạn cần các không gian tên để phân tích xung đột tên nếu bạn bạn kết hợp các tệp XML từ các nguồn khác nhau. Lấy một tệp XSLT làm ví dụ. Nó bao gồm các thành phần của không gian tên XSLT, các thành phần từ không gian tên của chính bạn, và (thường thì) các thành phần của không gian tên XHTML. Bằng cách sử dụng các không gian tên bạn có thể tránh sự nhập nhằng khó hiểu liên quan đến các thành phần có cùng tên địa phương. Không gian tên được xác định bởi URI (trong ví dụ này, http://univNaSpResolver/booklist). Để tránh việc sử dụng chuỗi dài như thế, bạn định nghĩa một tiền tố (prefix) mà gắn với URI này (trong ví dụ này, books). Xin nhớ rằng tiền tố cũng giống như một biến: tên của nó không thành vấn đề. Nếu hai tiền tố cùng tham chiếu tới một URI, không gian tên của các thành phần gắn với tiền tố sẽ giống nhau (xem ví dụ 1 trong Ví dụ 5). Một biểu thức XPath sử dụng các tiền tố (ví dụ, books:booklist/science:book) và, bạn phải cung cấp URI gắn với mỗi tiền tố. Đây là nơi mà NamespaceContext xuất hiện. Nó làm những việc đó. Bài viết này giải thích các cách khác nhau để cung cấp ánh xạ giữa tiền tố và URI. Trong tệp XML, ánh xạ được cung cấp bởi thuộc tính xmlns như: xmlns:books="http://univNaSpResolver/booklist" hoặc xmlns="http://univNaSpResolver/book" (không gian tên mặc định). Sự cần thiết của việc cung cấp sự phân giải không gian tên Nếu bạn có XML mà sử dụng các không gian tên, một biểu thức XPath sẽ thất bại nếu bạn không cung cấp một NamespaceContext. Ví dụ 0 trong Ví dụ 2 minh họa trường hợp này. Đối tượng XPath được xây dựng và ước lượng trên tài liệu XML. Đầu tiên, thử viết biểu thức mà không có các tiền tố không gian tên (result1). Trong phần hai, viết biểu thức với các tiền tố không gian tên result2). Ví dụ 2. Ví dụ 0 mà không có sự phân giải không gian tên private static void example0(Document example) throws XPathExpressionException, TransformerException { sysout("\n*** Zero example - no namespaces provided ***"); XPath xPath = XPathFactory.newInstance().newXPath(); NodeList result1 = (NodeList) xPath.evaluate("booklist/book", example, XPathConstants.NODESET); NodeList result2 = (NodeList) xPath.evaluate( "books:booklist/science:book", example, XPathConstants.NODESET); } Kết quả như sau. Ví dụ 3. Kết quả từ ví dụ 0 *** Zero example - no namespaces provided *** First try asking without namespace prefix: > booklist/book Result is of length 0 Then try asking with namespace prefix: > books:booklist/science:book Result is of length 0 The expression does not work in both cases. Trong cả hai trường hợp, sự ước lượng XPath không trả lại bất cứ nốt nào và không có ngoại lệ. XPath không thể tìm thấy nút nào bởi vì ánh xạ của các tiền tố tới các URI bị thiếu. Sự phân giải không gian tên được viết sẵn trong mã Hoàn toàn có thể cung cấp các không gian tên như là các giá trị có sẵn trong mã cái mà trông giống như lớp trong Ví dụ 4: Ví dụ 4. Sự phân giải không gian tên được viết sẵn public class HardcodedNamespaceResolver implements NamespaceContext { /** * This method returns the uri for all prefixes needed. Wherever possible * it uses XMLConstants. * * @param prefix * @return uri */ public String getNamespaceURI(String prefix) { if (prefix == null) { throw new IllegalArgumentException("No prefix provided!"); } else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) { return "http://univNaSpResolver/book"; } else if (prefix.equals("books")) { return "http://univNaSpResolver/booklist"; } else if (prefix.equals("fiction")) { return "http://univNaSpResolver/fictionbook"; } else if (prefix.equals("technical")) { return "http://univNaSpResolver/sciencebook"; } else { return XMLConstants.NULL_NS_URI; } } public String getPrefix(String namespaceURI) { // Not needed in this context. return null; } public Iterator getPrefixes(String namespaceURI) { // Not needed in this context. return null; } } Xin lưu ý rằng không gian tên http://univNaSpResolver/sciencebook được gắn với tiền tố technical (không phải science như trước). Bạn sẽ thấy hệ quả trong ví dụ sau (xem Ví dụ 6). Trong Ví dụ 5, đoạn mã sử dụng trình phân giải này sử dụng tiền tố mới. Ví dụ 5. Ví dụ 1 với sự phân giải không gian tên được viết sẵn trong mã private static void example1(Document example) throws XPathExpressionException, TransformerException { sysout("\n*** First example - namespacelookup hardcoded ***"); XPath xPath = XPathFactory.newInstance().newXPath(); xPath.setNamespaceContext(new HardcodedNamespaceResolver()); NodeList result1 = (NodeList) xPath.evaluate( "books:booklist/technical:book", example, XPathConstants.NODESET); NodeList result2 = (NodeList) xPath.evaluate( "books:booklist/fiction:book", example, XPathConstants.NODESET); String result = xPath.evaluate("books:booklist/technical:book/:author", example); } Kết quả như sau. Ví dụ 6. Kết quả từ ví dụ 1 *** First example - namespacelookup hardcoded *** Using any namespaces results in a NodeList: > books:booklist/technical:book Number of Nodes: 1 <?xml version="1.0" encoding="UTF-8"?> <science:book xmlns:science="http://univNaSpResolver/sciencebook"> <title xmlns="http://univNaSpResolver/book">Learning XPath</title> <author xmlns="http://univNaSpResolver/book">Michael Schmidt</author> </science:book> > books:booklist/fiction:book Number of Nodes: 2 <?xml version="1.0" encoding="UTF-8"?> <fiction:book xmlns:fiction="http://univNaSpResolver/fictionbook"> <title xmlns="http://univNaSpResolver/book">Faust I</title> <author xmlns="http://univNaSpResolver/book">Johann Wolfgang von Goethe</author> </fiction:book> <?xml version="1.0" encoding="UTF-8"?> <fiction:book xmlns:fiction="http://univNaSpResolver/fictionbook"> <title xmlns="http://univNaSpResolver/book">Faust II</title> <author xmlns="http://univNaSpResolver/book">Johann Wolfgang von Goethe</author> </fiction:book> The default namespace works also: > books:booklist/technical:book/:author Michael Schmidt Như bạn thấy, XPath đã tìm thấy các nút. Điều thuận lợi là bạn có thể thay đổi tên các tiền tố nếu bạn muốn, cái mà tôi đã thực hiện với tiền tố science. Tệp XML chứa tiền tố science, trong khi XPath sử dụng tiền tố khác, technical. Bởi vì các URI là giống nhau, các nốt được tìm thấy bởi XPath. Điều bất tiện là bạn phải duy trì các không gian tên ở nhiều nơi hơn: XML, có lẽ XSD, biểu thức XPath, và ngữ cảnh không gian tên. Đọc các không gian tên từ tài liệu Các không gian tên và các tiền tố của chúng được ghi chép trong các tệp XML, do đó bạn có thể sử dụng chúng từ đó. Cách dễ nhất là ủy nhiệm việc tìm kiếm cho tài liệu. Ví dụ 7. Sự phân giải không gian tên trực tiếp từ tài liệu public class UniversalNamespaceResolver implements NamespaceContext { [...]... thấy các không gian tên của thành phần gốc Để cho chính xác: các không gian tên của nút được truyền vào phương thức examineNode bởi phương thức khởi tạo Điều này làm tăng tốc phương thức khởi tạo bởi vì nó không phải lặp qua toàn bộ tài liệu Tuy nhiên, như bạn có thể thấy từ kết quả, tiền tố science không thể được phân giải Biểu thức XPath trả lại một ngoại lệ (XPathExpressionException) Đọc các không gian. .. Phiên bản tiếp theo này của NamespaceContext thì tốt hơn Nó đọc các không gian tên chỉ một lần trong phương thức khởi tạo Mọi lời gọi cho một không gian tên đều được trả lời từ một vùng đệm Và kết quả, một sự thay đổi trong tài liệu không ảnh hưởng khi mà danh sách các không gian tên được lưu trữ tạm thời tại thời điểm tạo đối tượng Java Ví dụ 10 Lưu trữ sự phân giải không gian tên trong vùng đệm từ... lục  Điều kiện tiên quyết và ví dụ  Nền tảng lý thuyết  Sự cần thiết của việc cung cấp sự phân giải không gian tên  Sự phân giải không gian tên được viết sẵn trong mã  Đọc các không gian tên từ tài liệu  Đọc các không gian tên từ tài liệu và lưu trữ trong vùng đệm  Đọc các không gian tên từ tài liệu và tất cả các thành phần của nó và lưu trong vùng nhớ đệm  Kết luận ... trước khi XPath được dùng, sự thay đổi sẽ được thể hiện trong việc tìm kiếm của không gian tên, bởi vì sự ủy nhiệm được hoàn tất khi cần sử dụng phiên bản hiện tại của tài liệu  Sự tìm kiếm các không gian tên hoặc các tiền tố được hoàn tất trong các nút tiền bối, trong trường hợp của chúng ta nút sourceDocument Điều này có nghĩa là, với đoạn mã được cung cấp, bạn chỉ lấy các không gian tên được mô... điều khiển qua các tệp XML, và ai đó có thể gửi cho bạn bất cứ tiền tố nào họ muốn, có lẽ cách tốt hơn hết là độc lập khỏi các lựa chọn của họ Bạn có thể viết mã sự phân giải không gian tên của chính bạn như trong Ví dụ 1 (HardcodedNamespaceResolver), và sử dụng chúng trong các biểu thức XPath của bạn Trong các trường hợp khác, NamespaceContext được phân giải từ tệp XML có thể làm cho mã của bạn tổng... bạn thấy trong kết quả, không gian tên được mô tả trong thành phần book với tiền tố science không được phân giải Phương thức ước lượng gửi trả lại một XPathExpressionException Để tránh vấn đề này, bạn có lẽ tách nốt science:book khỏi tài liệu và sử dụng nốt này như là sự ủy nhiệm Nhưng điều này có nghĩa bạn phải phân tích thêm tài liệu và không hiệu quả cho lắm Đọc các không gian tên từ tài liệu và lưu... cài đặt sự phân giải không gian tên mà có lẽ là tốt hơn việc viết sẵn chúng trong mã:  Nếu ví dụ của bạn là nhỏ và tất cả các không gian tên được định vị ở thành phần trên cùng, hãy ủy nhiệm việc tìm kiếm cho tài liệu  Nếu bạn có tệp XML lớn hơn với nhiều cấp độ lồng nhau và nhiều ước lượng XPath, có lẽ cách tốt hơn hết là lưu trữ tạm thời danh sách các không gian tên  Nhưng nếu bạn không phải điều... đọc các không gian tên, bạn phải đi đến nút con một cách chính xác Trong trường hợp này, sử dụng NamespaceContext thì đơn giản hơn: Ví dụ 11 Ví dụ 3 với sự phân giải không gian tên được lưu trữ tạm thời (chỉ cấp độ cao nhất) private static void example3(Document example) throws XPathExpressionException, TransformerException { sysout("\n*** Third example - namespaces of toplevel node cached ***"); XPath. .. chiến thắng Trong thực tế, điều này ít khi xảy ra Sử dụng NamespaceContext trong ví dụ này cũng giống như trong các ví dụ trước Biến logic toplevelOnly trong phương thức khởi tạo phải được đặt là false Ví dụ 13 Ví dụ 4 với sự phân giải không gian tên được lưu trữ trong vùng đêm (tất cả các cấp độ) private static void example4(Document example) throws XPathExpressionException, TransformerException {... levels cached ***"); XPath xPath = XPathFactory.newInstance().newXPath(); xPath. setNamespaceContext(new UniversalNamespaceCache(example, false)); NodeList result1 = (NodeList) xPath. evaluate( "books:booklist/science:book", example, XPathConstants.NODESET); NodeList result2 = (NodeList) xPath. evaluate( "books:booklist/fiction:book", example, XPathConstants.NODESET); String result = xPath. evaluate( "books:booklist/fiction:book[1]/:author", . Sử dụng đối tượng NamespaceContext của ngôn ngữ Java với XPath Các phương thức để phân tích các không gian tên với API của Java Holger Kraus, Chuyên gia IT,. thức XPath, và ngữ cảnh không gian tên. Đọc các không gian tên từ tài liệu Các không gian tên và các tiền tố của chúng được ghi chép trong các tệp XML, do đó bạn có thể sử dụng chúng từ đó. Cách. xmlns="http://univNaSpResolver/book" (không gian tên mặc định). Sự cần thiết của việc cung cấp sự phân giải không gian tên Nếu bạn có XML mà sử dụng các không gian tên, một biểu thức XPath sẽ thất bại nếu bạn không cung

Ngày đăng: 07/08/2014, 10:22

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan