ibm xml專區中對XPATH的一個好文,http://www.ibm.com/developerworks/cn/xml/x-xpathjava/
主要小結如下:
1 JDK 1.5中已經內建了很好的import javax.xml.xpath.XPathFactory;
了,用1.5吧
2 核心代碼
public XPathEvaluator(String xmlFilename) throws IOException {
try {
// Convert filename into a DOM tree
DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
this.domTree = builder.parse(xmlFilename);
} catch (SAXException e) {
throw new IOException("Error in document parsing: " + e.getMessage());
} catch (ParserConfigurationException e) {
throw new IOException("Error in configuring parser: " + e.getMessage());
}
}
public NodeList evaluateXPath(String xpathString) throws IOException {
try {
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
return (NodeList)xpath.evaluate(
xpathString, domTree, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
throw new IOException("Error evaluating XPath: " + e.getMessage());
}
}
public static void main(String[] args) {
try {
if (args.length != 1) {
System.err.println("Usage: java ibm.dw.xpath.XPathEvaluator " +
"[XML filename]");
System.exit(1);
}
XPathEvaluator evaluator = new XPathEvaluator(args[0]);
String xpathString = "//target[@name='init']/property[" +
"starts-with(@name, 'parser')]";
NodeList results = evaluator.evaluateXPath(xpathString);
for (int i=0; i<results.getLength(); i++) {
Node node = results.item(i);
System.out.print("Result: ");
switch (node.getNodeType()) {
case Node.ELEMENT_NODE: System.out.println("Element node named " +
node.getNodeName());
break;
case Node.ATTRIBUTE_NODE: System.out.println(
"Attribute node named " +
node.getNodeName() + " with value '" +
node.getNodeValue() + "'");
break;
case Node.TEXT_NODE: System.out.println("Text: '" +
node.getNodeValue() + "'");
break;
default: System.out.println(node);
}
}
可見其基本步驟為,1 讀入一個XML
2 建立DOMTREE,即:
DocumentBuilderFactory domFactory =
DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
this.domTree = builder.parse(xmlFilename);
3 String xpathString = "//target[@name='init']/property[" +
"starts-with(@name, 'parser')]";
NodeList results = evaluator.evaluateXPath(xpathString);
這裡向該方法傳入xpath.其中evaluatexpath方法的功能為把domtree中用xpath解析後,返回一個nodelist,然後再解析.
4 建立XPATH工廠
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
return (NodeList)xpath.evaluate(
xpathString, domTree, XPathConstants.NODESET);
XPathFactory是一個抽象工廠.
抽象工廠設計模式使得這一種 API 能夠支援不同的物件模型,如 DOM、JDOM 和 XOM.
為了選擇不同的模型,需要向XPathFactory.newInstance()方法傳遞標識物件模型的統一資源識別項(URI).
目前只支援DOM.
之後建立xpath對象.
之後應用xpath運算式
其中evaluate() 方法被聲明為返回 Object,實際返回什麼依賴於 XPath 運算式的結果以及要求的類型
一般來說,XPath與Java的映射關係是:
number 映射為 java.lang.Double
string 映射為 java.lang.String
boolean 映射為 java.lang.Boolean
node-set 映射為 org.w3c.dom.NodeList
在 Java 中計算 XPath 運算式時,第二個參數(XPathConstants常量)指定需要的傳回型別.有五種可能,都在 javax.xml.xpath.XPathConstants 類中命名了常量:
XPathConstants.NODESET
XPathConstants.BOOLEAN
XPathConstants.NUMBER
XPathConstants.STRING
XPathConstants.NODE
XPathConstants.NODE提示:
最後一個 XPathConstants.NODE 實際上沒有匹配的 XPath 類型.只有知道 XPath 運算式只返回一個節點或者只需要一個節點時才使用它.如果 XPath 運算式返回了多個節點並且指定了 XPathConstants.NODE,則 evaluate() 按照文檔順序返回第一個節點.如果 XPath 運算式選擇了一個空集並指定了 XPathConstants.NODE,則 evaluate() 返回 null.
注意:如果不能完成要求的轉換,evaluate()將拋出 XPathException
最後,可以轉換為DOM的NodeList進行解析.
一個更典型的小例子如下:
DocumentFactory factory=DocumentFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc=builder.parse("src/books.xml");
XpathFactory xpathfactory=XpathFactory.newInstance();
Xpath xpath=xpathfactory.newXpath();
XPathExpression pathExpression = xpath
.compile("//book[author='TEST']/title/text()");
Object result=pathExpression.evalucate(doc,XPathConstants.NODESET);
NodeList nodes=(NodeList)result;
for (i=0;i<=nodes.getLenth();i++)
System.out.println(nodes.item(i).getNodevalue):