程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 使用JXPath訪問java對象、集合和XML文件

使用JXPath訪問java對象、集合和XML文件

編輯:關於JAVA

一、JXPath簡介

JXPath是apache公司提供的XPath的java實現,屬於jakarta的一部分,最新的版本是1.1,JXPath的主要功能在於一組java類庫來使用XPath的方式訪問符合JavaBeans規范的java類、java集合(Collections)、其他具有動態屬性的對象(如Map、ServletContext等),同時提供了一套擴展機制使我們可以增加對這些對象之外的其他對象模型的支持。

[注]

1、關於XPath的更多內容請大家訪問XPath的主頁

asp">http://www.w3schools.com/xpath/default.asp

2、關於JXPath的更多內容請大家訪問JXPath的主頁

http://jakarta.apache.org/commons/jxpath/index.html

二、環境准備

1、下載JXPath

JXPath最新版本的二進制代碼下載地址為

http://apache.linuxforum.net/dist/jakarta/commons/jxpath/binaries/commons-jxpath-1.1.zip

2、下載eclipse

作者使用了eclipse作為開發工具,請大家到http://www.eclipse.org/下載eclipse的最新版本。

3、下載Tomcat

作者使用了Tomcat作為Web容器來演示如何使用JXPath訪問ServletContext中的對象,請大家到jakarta.apache.org下載Tomcat的最新版本。

下面的幾個章節將詳細的演示如何使用JXPath來訪問各種各樣的對象,同時將演示如何通過JXPath來創建對象、修改對象的屬性等功能。

三、使用JXPath訪問對象內容3.1 訪問JavaBean的屬性

1、准備一個符合要求的Java類

作者制作了一個Company類,它包括3個屬性:ID、Name和Address,代碼如下:package org.vivianj.jxpath.examples.pub;
import java.util.Comparator;
import org.apache.log4j.Logger;
public class Company implements Comparator{
public static Logger logger = Logger.getLogger(Company.class);
private String name = "";
private int id = 0;
private String address = "";
public void setName(String p_name){
this.name = p_name;
}
public void setId(int p_id){
this.id = p_id;
}
public void setAddress(String p_address){
this.address = p_address;
}
public String getName(){
return this.name;
}
public int getId(){
return this.id;
}
public String getAddress(){
return this.address;
}
public int compare(Object o1, Object o2){
return 0;
}
public boolean equals(Object obj) {
boolean result = false;
if (obj instanceof Company){
Company company = (Company) obj;
if (company.getId()==this.id
&& company.getName().equals(this.getName())
&& company.getAddress().equals(this.getAddress()))
result = true;
}
return result;
}
}

2、使用JXPath來訪問該java類的屬性

現在我們使用JXPath來訪問這個類的屬性,測試代碼如下://實例化一個Company對象
Company company = new Company();
//設置該對象的各個屬性
company.setId(1);
company.setName("vivianj組織");
company.setAddress("www.vivianj.org");
//初始化JXPath的上下文環境
JXPathContext context = JXPathContext.newContext(company);
//使用XPath語法來訪問該對象的屬性
//getValue方法的參數"name"、"id"、"address"使用了XPath的語法,
//他們分別代表要訪問company對象的屬性name、id、address
String name = (String)context.getValue("name");
Integer id = (Integer) context.getValue("id");
String address = (String)context.getValue("address");

3.1.1 Lenient 訪問模式

在上面的訪問方式中有可能會出現這樣的情況:如果你要訪問的屬性不是這個Java類的屬性,那麼執行過程中系統會報出一個違例-- org.apache.commons.jxpath.JXPathException: No value for xpath: xxx(xxx是你要訪問的屬性的名稱)。

這種情況對於程序的穩定性、健壯性是有害的,這時候我們應該使用JXPath提供的Lenient 訪問模式來避免出現這樣的情況,在Lenient 訪問模式下,如果你訪問了不存在的屬性,系統會返回一個null,而不是拋出一個違例。

要使用Lenient 訪問模式非常簡單,只需要在代碼中增加context.setLenient(true)調用就可以了,具體操作如下:

//實例化一個Company對象
Company company = new Company();
//設置該對象的各個屬性
company.setId(1);
company.setName("vivianj組織");
company.setAddress("www.vivianj.org");
//初始化JXPath的上下文環境
JXPathContext context = JXPathContext.newContext(company);
//通知系統使用Lenient 訪問模式
context.setLenient(true)
//使用XPath語法來訪問該對象的屬性
String name = (String)context.getValue("name1");

[注] name1 不是Company類的屬性,但是由於使用了Lenient 訪問模式,所以系統返回null。

3.2 訪問嵌套屬性

3.1中的例子演示了如何訪問類的簡單類型屬性,如果類的屬性本身就是一個類類型,情況會怎麼樣呢,下面的例子將演示這種訪問方式:

1、准備Association類

Association類有一個屬性company,他本身是Company類類型package org.vivianj.jxpath.examples.pub;
import java.util.ArrayList;
import java.util.Collection;
public class Association {
private Company company;
public Company getCompany(){
return this.company;
}
public void setCompany(Company p_company){
this.company = p_company;
}
}

2、用JXPath訪問嵌套屬性//實例化Association類
Association association = new Association();
//實例化Company類
Company company = new Company();
company.setId(1);
company.setName("vivianj組織");
company.setAddress("www.vivianj.org");
//設置Association對象的company屬性
association.setCompany(company);
//初始化JXPath上下文
JXPathContext context = JXPathContext.newContext(association);
//使用Lenient訪問模式訪問嵌套屬性
context.setLenient(true);
//通過JXPath方法獲得指定屬性的值
//其中getValue方法的參數"company/name"的
//第一部分company代表Association的屬性company,
//第二部分("/"符號後面的部分)name代表是company對象的屬性
String name = (String) context.getValue("company/name");

3.3 訪問Java集合

JXPath可以訪問Java集合的內容,這些集合包括java數組、Collection類及其子類,他們的訪問方式基本類似,詳細的情況請參照下面的程序代碼:

1、擴展Association類,增加一個提供Company對象的數組的方法

給Association類增加一個方法getCompanysInArray方法,方法的簽名和內容如下:public Company[] getCompanysInArray(){
for (int i = 0 ; i < 5 ; i++){
//實例化新的Company對象
Company comp = new Company();
comp.setId(i);
comp.setName("Name" + i );
comp.setAddress("address" + i);
//將實例化的對象賦值給到數組的對應元素
companysInArray[i] = comp;
}
return companysInArray;
}

2、擴展Association類,增加一個提供Company對象的Collection的方法

給Association類增加一個方法getCompanysInCollection方法,方法的簽名和內容如下:public Collection getCompanysInCollection(){
for (int i = 0 ; i < 5 ; i++){
//實例化新的Company對象
Company comp = new Company();
comp.setId(i);
comp.setName("Name" + i );
comp.setAddress("address" + i);
//將實例化的對象增加到Collection中
companysInCollection.add(comp);
}
return companysInCollection;
}

3.3.1 訪問方法

通過JXPath訪問數組的詳細代碼如下:

//實例化Association類
Association association = new Association();
//初始化JXPath上下文
JXPathContext context = JXPathContext.newContext(association);
//使用Lenient訪問模式訪問嵌套屬性
context.setLenient(true);
//通過JXPath語法訪問數組下標為4的記錄的name屬性
//getValue方法的參數"companysInArray[5]/name"中的
//部分companysInArray是Association的屬性,
//5代表訪問數組中第5個元素,name表示第五個元素的屬性名
String name = (String) context.getValue("companysInArray[5]/name");
//通過XPath語法訪問集合中第4條記錄的name屬性
//getValue方法的參數" companysInColletion[5]/name"中的
//部分companysInColletion是Association的屬性名,
//5代表訪問集合中第5個元素,name表示第五個元素的屬性名
String name = (String) context.getValue("companysInColletion[5]/name");

[注] XPath訪問數組或者集合時,數組或者集合的下標是從1開始,這點和java語言中規定的從0開始有點不同

3.3.2 獲取多條記錄

既然是訪問集合數據,那麼經常會出現這樣的需求:需要獲得符合條件的多條記錄。這種情況使用JXPath也非常方便,使用context對象的iterator方法加上相應的XPath信息就可以了,操作後返回的內容保存在Iterator對象中,非常方便就可以訪問。具體的代碼如下:

1、按記錄所在的位置獲取//實例化Association類
Association association = new Association();
//實例化JXPath上下文
JXPathContext context = JXPathContext.newContext(association);
//獲得數組中下標大於3的所有記錄
//iterator方法的參數companysInArray [position() > 3]使用了XPath的語法
//其中的companysInArray是Association對象的屬性,他是一個數組
// position()是XPath中的內置函數,獲得記錄在數組中的下標
Itarator companysInArray =
context.iterate("companysInArray [position() > 3]");
//獲得集合中所處位置大於3的所有記錄
//iterator方法的參數companysInCollection [position() > 3]使用了XPath的語法
//其中的companysInCollection是Association對象的屬性
//他是一個Collection類型或者是其子類型的一個實例
//position()是XPath中的內置函數,獲得記錄在集合中的位置
Itarator companysInCollection =
context.iterate("companysInCollection [position() > 3]");

2、按指定的規則獲取//實例化Association類
Association association = new Association();
//實例化JXPath上下文
JXPathContext context = JXPathContext.newContext(association);
//獲得數組中對象的name屬性為'name3'的所有對象
//iterator方法的參數companysInArray [name='name3']使用了XPath的語法
//其中的companysInArray是Association對象的屬性,他是一個數組
//name='name3'是條件表達式,表示返回對象的name屬性值必須是name3
Itarator companysInArray =
context.iterate("companysInArray [name='name3']");
//獲得集合中對象的name屬性為'name2'的所有對象
//iterator方法的參數companysInCollection [name='name3']使用了XPath的語法
//其中的companysInCollection是Association對象的屬性
//他是一個Collection類型或者是其子類型的一個實例
//name='name3'是條件表達式,表示返回對象的name屬性值必須是name3
Itarator companysInCollection =
context.iterate("companysInCollection [name='name3']");

3.4 訪問Map對象的內容

1、准備符合條件的java類package org.vivianj.jxpath.examples.pub;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.jxpath.JXPathContext;
public class MyMapSource {
private Map map = new HashMap();
public MyMapSource(){
map.put("id",new Integer(5));
map.put("name","name");
}
public Map getMapSource(){
return this.map;
}
}

2、使用JXPath訪問Map的內容//實例化MyMapSource對象
MyMapSource myMapSource = new MyMapSource();
//實例化JXPath上下文
JXPathContext context = JXPathContext.newContext(myMapSource);
//通過JXPath訪問Map對象的內容
// getValue方法的參數使用了XPath語法
// mapSource/id中的mapSource表示MyMapSource對象的屬性,
//他是一個Map類型的對象,id表示獲取該Map對象的id字段
Integer id = (Integer) context.getValue("mapSource/id");

3.5 訪問XML文件

1、編寫自己的XML文件<?xml version="1.0" ?>
<companys>
<company id="101">
<name>sun</name>
<address>
<street>18 #,WenShan Road</street>
</address>
</company>
<company id="102">
<name>ibm</name>
<address>
<street>18 #,WenEr Road</street>
</address>
</company>
</companys>

2、編寫一個類,返回符合條件的company內容package org.vivianj.jxpath.examples.pub;
import java.net.URL;
import org.apache.commons.jxpath.Container;
import org.apache.commons.jxpath.xml.DocumentContainer;
public class Companys {
private Container companys = null;
public Container getCompanys(){
if (companys == null){
//獲取XML文件的內容
URL url = getClass().getResource("companys.xml");
//將XML的內容綁定到companys對象
companys = new DocumentContainer(url);
}
return companys;
}
}

3、使用JXPath訪問XML文件的內容//實例化Companys對象
Companys companys = new Companys();
//初始化JXPath上下文
JXPathContext context = JXPathContext.newContext(companys);
//獲得指定記錄的子元素的內容
/*getValue方法的參數
"companys/companys/company[@id = '101']/address/street"
使用了XPath語法
其中的第一個companys表示訪問Companys對象的companys屬性
第二個companys表示訪問XML數據中的companys元素
company、address、street都是xml中的元素的名字
@id = '101'是一個條件表達式,表示符合條件的company元素的id屬性必須是101
*/
String street = (String)context.getValue(
"companys/companys/company[@id = '101']/address/street");
//通過JXPath獲取xml元素的屬性的值
logger.debug("id=" +
context.getValue("companys/companys/company[@id = '101']/@id"));
//通過JXPath獲取xml元素的子元素的值
logger.debug("p_id=" +
context.getValue("companys/companys/company[name = 'sun']/name"));

[注] 通過JXPath訪問xml內容時,如果訪問屬性,必須增加一個@符號,以示區別

四、總結

JXPath是apache組織提供的一個XPath的java實現,目前最新的版本是1.1,通過JXPath提供的豐富的類庫,使用者可以很簡單的使用XPath語法來訪問java對象、集合、xml內容、web應用環境下的各種對象等。

本文中作者一開始簡單的介紹了JXPath的相關信息,接下來的章節中,作者結合實例,詳細的演示了如何通過JXPath提供的豐富的類庫訪問java對象、集合和XML文件的詳細過程,同時給出了簡單的注釋,希望能夠幫助大家進入JXPath的精彩世界。JXPath的強大功能遠不止此,請大家關注作者的後續文章。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved