Nếu bạn gửi một ai đó mua cho bạn một chai sữa thì bạn sẽ đề nghị như thế nào đến người đó để nhờ họ mua cho bạn? "Làm ơn mua hộ tôi một chai sữa" hay là nói "Đi ra ngoài thông qua cửa trước. Rẽ trái ở phần vỉa hè dành cho người đi bộ. Đi bộ qua ba ngã tư. Rẽ phải. Đi bộ thêm một đoạn nữa. Rẽ phải và đi vào cửa hàng. Đi tới gian thứ tư. Đi bộ khoảng năm mét rồi đi xuống gian dưới. Rẽ trái. Cầm lấy một hộp sữa. Mang hộp sữa ra bàn thanh toán. Thanh toán tiền cho chai sữa đó. Và sau đó đi ngược lại đoạn đường vừa đi để đi về nhà bạn." Điều này thật là nực cười. Hầu hết đứa trẻ đều đủ thông minh để biết cách mang hộp sữa về nhà với một lời chỉ dẫn đơn giản "Làm ơn mua hộ tôi một chai sữa".
Các ngôn ngữ truy vấn và cơ chế tìm kiếm của máy tính cũng tương tự như nhau. Việc "Tìm bản sao của Cryptonomicon" dễ dàng hơn là việc viết ra một cấu trúc logic chi tiết để tìm kiếm một số cơ sở dữ liệu. Bởi vì các thao tác tìm kiếm có logic rất giống nhau nên bạn có thể đưa ra các ngôn ngữ tổng quát để có thể thực hiện câu lệnh như "Tìm tất cả các quyển sách của tác giả Neal Stephenson," và sau đó viết một cơ chế xử lý các truy vấn đó dựa vào các kho dữ liệu nào đó.
Trong rất nhiều ngôn ngữ truy vấn, Ngôn ngữ Truy vấn Có cấu trúc (SQL) là ngôn ngữ được thiết kế và cho phép thực hiện truy vấn trên các cơ sở dữ liệu quan hệ. Có một số ít các ngôn ngữ truy vấn bao gồm Ngôn ngữ truy vấn đối tượng (OOL) và XQuery. Tuy nhiên, chủ đề chính của bài viết này là về XPath cho nên ngôn ngữ truy vấn được thiết kế để thực hiện xử lý truy vấn trên các tài liệu XML. Ví dụ, một truy vấn XPath đơn giản là tìm ra các tiêu đề của tất cả các quyển sách trong tài liệu của tác giả Neal Stephenson, truy vấn phải trông có dạng như sau:
//book[author="Neal Stephenson"]/title |
Ngược lại, cơ chế tìm kiếm DOM thuần túy cho phép có thông tin cho dưới dạng như trong Ví dụ 1:
Ví dụ 1. Mã DOM để tìm tất cả các tiêu đề của các phần tử book có giá trị Neal Stephenson
ArrayList result = new ArrayList();
NodeList books = doc.getElementsByTagName("book");
for (int i = 0; i < books.getLength(); i++) {
Element book = (Element) books.item(i);
NodeList authors = book.getElementsByTagName("author");
boolean stephenson = false;
for (int j = 0; j < authors.getLength(); j++) {
Element author = (Element) authors.item(j);
NodeList children = author.getChildNodes();
StringBuffer sb = new StringBuffer();
for (int k = 0; k < children.getLength(); k++) {
Node child = children.item(k);
// really should to do this recursively
if (child.getNodeType() == Node.TEXT_NODE) {
sb.append(child.getNodeValue());
}
}
if (sb.toString().equals("Neal Stephenson")) {
stephenson = true;
break;
}
}
if (stephenson) {
NodeList titles = book.getElementsByTagName("title");
for (int j = 0; j < titles.getLength(); j++) {
result.add(titles.item(j));
}
}
}
|
Điều này có thể tin hoặc không, đoạn mã DOM trong Ví dụ 1 thực sự không mang tính tổng quát và dõ dàng bằng các biểu thức XPath đơn giản. Cái mà cho phép bạn có thể viết, sửa lỗi và bảo trì được tốt hơn? Tôi nghĩ câu trả lời đã rất rõ dàng.
Có một điều phải nhớ rằng XPath không phải là ngôn ngữ Java -- trong thực tế, XPath không hoàn toàn là một ngôn ngữ lập trình. Có nhiều vấn đề bạn không thể thấy được ở trong XPath, thậm chí kể cả các câu lệnh truy vấn cũng không thể được tạo ra trong XPath. Ví dụ, XPath không không thể tìm thấy các quyển sách đã đăng ký số quốc tế (ISBN) nếu kiểm tra không phù hợp các mã chữ số hay các tác giả của cuốn sách đó được lấy từ cơ sở dữ liệu tài khoản bên ngoài. Thật may mắn, khi bạn tích hợp XPath vào trong chương trình Java thì bạn có thể tận dụng được ưu thể của cả hai ngôn ngữ này: Java sẽ giải quyết tốt những vấn đề liên quan đến Java, tương tự XPath sẽ giải quyết tốt những vấn đề liên quan tới XPath.
Cho đến thời điểm gần đây, giao diện lập trình ứng dụng (API) được các chương trình Java sử dụng để tạo ra các câu truy vấn XPath khác nhau dựa trên cơ chế XPath. Xalan có một API, Saxon có một loại khác và các cơ chế khác sẽ có các API khác. Điều này có nghĩa rằng đoạn mã của bạn theo yêu cầu hướng vào một sản phẩm nào đó của bạn. Theo một ý nào đó, bạn có thể làm thử nghiệm với các cơ chế khác nhau để có được các đặc trưng cơ bản khác nhau mà không quá phức tạp hoặc không cần phải viết lại đoạn mã.
Vì lý do này, Java 5 giới thiệu gói javax.xml.xpath cung cấp đầy đủ các cơ chế, ứng dụng và mô
hình đối tượng độc lập thư viện XPath. Gói này cũng có thể áp dụng được
trong Java 1.3 và các phiên bản sau nếu bạn có cài đặt phần Java API for
XML Processing (JAXP) 1.3. Nằm trong các sản phẩm khác, Xalan 2.7 và Saxon
8 bao gồm các thực thi của thư viện này.
Tôi sẽ bắt đầu bằng việc mô phỏng một cách chính xác các bước để thực hành trong phần này. Sau đó tôi sẽ tập trung nghiên cứu vào một số vấn đề chi tiết cụ thể. Giả sử bạn muốn truy vấn ra danh sách các quyển sách của tác giả Neal Stephenson. Trong trường hợp này, danh sách trong biểu mẫu được hiện thị như trong Ví dụ 2:
Ví dụ 2. Tài liệu XML chứa thông tin các quyển sách
<inventory>
<book year="2000">
<title>Snow Crash</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<isbn>0553380958</isbn>
<price>14.95</price>
</book>
<book year="2005">
<title>Burning Tower</title>
<author>Larry Niven</author>
<author>Jerry Pournelle</author>
<publisher>Pocket</publisher>
<isbn>0743416910</isbn>
<price>5.99</price>
</book>
<book year="1995">
<title>Zodiac</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<isbn>0553573862</isbn>
<price>7.50</price>
</book>
<!-- more books... -->
</inventory> |
Truy vấn XPath cho phép tìm ra tất cả các quyển sách một cách đơn giản:
//book[author="Neal Stephenson"]. Để tìm
tiêu đề của những cuốn sách này thì đơn giản chỉ làm thêm một bước và lúc
đó biểu thức sẽ có dạng //book[author="Neal
Stephenson"]/title. Cuối cùng, nếu bạn muốn truy vấn các nút
con của phần tử title. Bạn sẽ phải làm thêm một
bước nữa để có một biểu thức đầy đủ như sau //book[author="Neal Stephenson"]/title/text().
Bây giờ tôi sẽ đưa ra một chương trình đơn giản để thực hiện tìm kiếm này
từ ngôn ngữ Java và sau đó in ra tiêu đề của tất cả các quyển sách tìm
được. Đầu tiên bạn cần phải tải được toàn bộ tài liệu vào đối tượng DOM
Document. Để đơn giản, tôi sẽ giả định rằng
tài liệu được sử dụng là tệp books.xml nằm trong cùng thư mục làm việc
hiện thời. Đây là một phân mã đơn giản để thực hiện phân tích tài liệu và
tạo ra đối tượng Document tương ứng:
Ví dụ 3. Sự phân tích tài liệu bằng JAXP
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true); // never forget this!
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("books.xml"); |
Đây là chuẩn JAXP và DOM, là chuẩn đã được trình bày và được nghiên cứu.
Tiếp theo bạn tạo ra XPathFactory:
XPathFactory factory = XPathFactory.newInstance(); |
Sau đó bạn sử dụng factory để tạo ra đối tượng XPath:
XPath xpath = factory.newXPath(); |
Đối tượng XPath thực hiện biên dịch biểu thức
XPath:
XPathExpression expr = xpath.compile("//book[author='Neal Stephenson']/title/text()"); |
Cuối cùng, bạn thực hiện đánh giá biểu thức XPath để nhận được kết quả. Khi biểu thức được đánh giá với mục đích đưa ra nội dung cụ thể của nút thì trong trường hợp này cần phải làm việc bên trong toàn bộ tài liệu. Nó cũng cần thiết phải xác định kiểu trả lại:
Object result = expr.evaluate(doc, XPathConstants.NODESET); |
Sau đó bạn có thể gộp kết quả tới DOM NodeList
và thực hiện lặp đi lặp lại để tìm ra tất cả các tiêu đề:
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue());
} |
Ví dụ 4 đặt tất cả vào thành một chương trình đơn
giản. Chú ý rằng các phương thức này cũng có thể nắm bắt được một số ngoại
lệ kiểm tra vì thế phải mô tả thêm mệnh đề throws:
Ví dụ 4. Một chương trình hoàn thiện để thực hiện truy vấn tài liệu XML với một biểu thức XPath xác định
import java.io.IOException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
public class XPathExample {
public static void main(String[] args)
throws ParserConfigurationException, SAXException,
IOException, XPathExpressionException {
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true); // never forget this!
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("books.xml");
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr
= xpath.compile("//book[author='Neal Stephenson']/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());
}
}
} |
Khi bạn trộn hai ngôn ngữ khác nhau như XPath và Java, bạn cần chú ý tới các điểm nối của hai ngôn ngữ đó. Tất nhiên không phải mọi điều phù hợp đều đúng. Ngôn ngữ Java và XPath không phải là hai hệ thống giống hệt nhau. XPath 1.0 chỉ có bốn kiểu cơ bản sau:
- Tập hợp nút (node-set)
- Kiểu số (number)
- Kiểu logic (boolean)
- Kiểu chuỗi ký tự (string)
Trong ngôn ngữ Java có nhiều kiểu hơn bao gồm cả các kiểu đối tượng được định nghĩa bởi người sử dụng.
Hầu hết các biểu thức XPath, đặc biệt là các đường dẫn, sẽ là các bộ nút.
Tuy nhiên, có thể có một số khả năng khác. Ví dụ, Biểu thức count(//book) trả lại số các quyển sách có trong
tài liệu. Biểu thức XPath count(//book[@author="Neal
Stephenson"]) > 10 trả lại một luận lý: đúng nếu có nhiều
hơn 10 quyển sách của tác giả Neal Staphenson trong tài liệu ngược lại nếu
có ít hơn 10 quyển sách trong tài liệu, sai nếu nếu có ít hơn 10.
Phương thức evaluate() được mô tả trả lại Object. Đối tượng 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
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
http://www.example.com/books 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
<inventory xmlns="http://www.example.com/books">
<book year="2000">
<title>Snow Crash</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<isbn>0553380958</isbn>
<price>14.95</price>
</book>
<!-- more books... -->
</inventory> |
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 http://www.example.com/books. 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 "http://www.example.com/books";
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());
} |
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 http://www.example.com/books 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("http://www.example.com/books", "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.
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.
Học tập
- ""Bắt
đầu với XPath 2.0" của tác giả Benoît Marchal
(developerWorks, May 2006): Với sự gia tăng sức mạnh và tính hiệu quả của
XPath phiên bản 2.0, học cách viết dễ dàng các yêu cầu phức tạp với mô
hình dữ liệu mới.
- "Làm
việc với các ngữ cảnh không gian tên JAXP:" Norm Walsh biện hộ cho
các ngữ cảnh không gian tên..
-
XML in a
Nutshell
(Elliotte Rusty Harold and W. Scott Means, O'Reilly, 2005): Đọc bài
tham khảo đầy đủ này và bài hướng dẫn ngắn về XPath 1.0, cũng như DOM và
JAXP.
-
developerWorks Java technology zone: Khám phá hàng trăm bài viết
về mọi khía cạnh của lập trình Java.
-
Chứng chỉ IBM
XML 1.1: Học cách để trở thành nhà phát triển XML 1.1 và các công
nghệ liên quan được chứng nhận bởi IBM.
-
XML: Thăm developerWorks XML Zone với rất nhiều bài viết và mẹo,
hướng dẫn, tiêu chuẩn và các sách đỏ của IBM.
-
Web quảng bá và các sự kiện kỹ thuật của developerWorks: Cập nhật
kiến thực công nghệ của bạn ở đây.
Lấy sản phẩm và công nghệ
-
JAXP Project: Tải 1.3 cho Java
1.3 và 1.4 từ java.net.
-
Xalan 2: Khám phá cỗ máy XSLT
của dự án Apache mà hỗ trợ các hàm API XPath trong bài viết
này.
-
SAXON 8: Thử cỗ máy XSLT của
Michael Kay mà cũng hỗ trợ API XPath được thảo luận trong bài viết
này.
-
Phần mềm dùng thử của IBM: Xây dựng dự án tiếp theo của bạn với
phần mềm dùng thử tải về từ developerWorks.
Thảo luận
-
Các diễn đàn thảo luận về XML: Tham dự vào các diễn đàn
XML.
-
developerWorks blogs: Tham gia vào cộng đồng
developerWorks.
Elliotte Rusty Harold sinh ra ở New Orleans, nơi mà ông thường xuyên trở về để thưởng thức món mướp tây. Tuy nhiên, ông sống ở Prospect Heights cạnh Brooklyn với vợ tên là Beth và hai con là Charm và Marjorie. Ông là trợ lý giáo sư ngành khoa học máy tính tại trường đại học Polytechnic University, nơi mà ông dạy môn Java và lập trình hướng đối tượng