1. 程式人生 > >dom4j使用XPath解析XML返回null的解決方法

dom4j使用XPath解析XML返回null的解決方法

使用XPath解析XML的時候,在基本程式碼沒有寫錯的情況下,使用selectSingleNode()方法獲取xml的內容時返回null值,很有可能是因為xml設定了名稱空間。

1)在沒有名稱空間的情況下,book.xml的檔案(檔案位於src/cn/edu/gdut/web/xpath下)內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<books>
	<book>
		<name>thinking in java</name>
		<author>Bruce Eckel</author>
		<price>108</price>
	</book>
	<book>
		<name>c primer plus</name>
		<author>Stephen Prata</author>
		<price>89</price>
	</book>
</books>

假如需要獲取第一個book下的name,步驟如下:

首先建立SAXReader物件的一個例項saxReader,其次利用saxReader呼叫方法read()訪問xml的地址得到Document物件的一個例項doc,然後利用doc呼叫方法selectSingleNode()來讀取第一個book的name。程式碼實現如下:

package cn.edu.gdut.web.xpath;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.*;

public class TestXPath {
	
	@Test
	public void testNoNameSpace() throws DocumentException {
		SAXReader saxReader = new SAXReader();
		Document doc = saxReader.read("src/cn/edu/gdut/web/xpath/book.xml");
		Node node = doc.selectSingleNode("/books/book[1]/name");
		System.out.println(node.getText());
	}
	
}

2)但是當為xml添加了名稱空間以後,book.xml檔案內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<books xmlns="http://www.gdut.edu.cn">
	<book>
		<name>thinking in java</name>
		<author>Bruce Eckel</author>
		<price>108</price>
	</book>
	<book>
		<name>c primer plus</name>
		<author>Stephen Prata</author>
		<price>89</price>
	</book>
</books>

我們再使用之前上面的程式碼獲取第一個book的name時,會返回一個null值,此時我們就應該對xpath進行預處理,步驟如下:

首先應該建立SAXReader物件的一個例項saxReader;其次把xml的namespace內容存放到Map中;然後把map的內容作為namespace的路徑(我這裡的namespace是http://www.gdut.edu.cn),此步驟主要是利用saxReader呼叫getDocumentFactory()方法,隨之再呼叫setNameSpaceURIs()方法,將map新增進去;隨後使用saxReader呼叫read()方法獲得Document對像的一個例項doc,最後利用doc呼叫selectSingleNode()獲取一個Node物件例項node,在使用select·SingleNode()方法時,所有節點需要在前面加上map的key值(這裡我使用的是gdut),程式碼實現如下:

package cn.edu.gdut.web.xpath;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.*;

public class TestXPath {
	
	@Test
	public void testNameSpace() throws DocumentException {
		SAXReader saxReader = new SAXReader();
		Map<String, String> map = new HashMap<String, String>();
		map.put("gdut", "http://www.gdut.edu.cn");
		saxReader.getDocumentFactory().setXPathNamespaceURIs(map);
		Document doc = saxReader.read("src/cn/edu/gdut/web/xpath/book.xml");
		Node node = doc.selectSingleNode("/gdut:books/gdut:book[1]/gdut:name");
		System.out.println(node.getText());
	}
	
}