XML解析方式分为两种:①DOM(Document Object Model 文件对象模型) API/技术有:Jdom → Dom4j ②SAX(Simple API for XML)API/技术有:JAXP(SUN/dom/SAX)
Dom4j和SAX技术的区别:
Dom4j读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用dom4j的 接口来操作这个树结构,包括增删改查。缺点是占用了较多内存。一般用在一旦解析了文档还需多次访问这些数据并且内存资源充足的情况下。
SAX为事件驱动, 当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员只要编写处理这些事件的代码,保存数据即可。它不用事先读入整个文档,占用资源少。缺点是不能进行多次访问,一旦时间过后若没保存数据则数据就不能再次访问了,且不知获得的文本属于哪一个元素。一般用在内存资源少的情况。
现在内存资源的限制很小了,dom4j功能强大,操作简单,所以常常使用dom4j技术来解析XML。
由于Dom4j不是SUN公司的,是开源组织的,所以在使用的时候必须先导入Dom4j的jar包。该包的下载地址为:http://sourceforge.net/projects/dom4j/files/
因为Dom4j是解析XML的,所以XML文档每一个组成(元素、属性、注释、CDATA等)在Dom4j 的API中都可以找到。
下面是Dom4j的主要接口:
Attribute定义了XML的属性
| |
Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为,
| |
CDATA 定义了XML CDATA 区域
| |
CharacterData是一个标识接口,标识基于字符的节点。如CDATA,Comment, Text.
| |
Comment 定义了XML注释的行为
| |
定义了XML文档
| |
DocumentType 定义XML DOCTYPE声明
| |
Element定义XML 元素
| |
ElementHandler定义了 Element 对象的处理器
| |
被
ElementHandler 使用,用于取得当前正在处理的路径层次信息
| |
Entity定义 XML entity
| |
Node为所有的dom4j中XML节点定义了多态行为
| |
NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)
| |
ProcessingInstruction 定义 XML 处理指令.
| |
Text 定义XML 文本节点.
| |
Visitor 用于实现Visitor模式.
| |
XPath 在分析一个字符串后会提供一个XPath 表达式
|
dom4j解析XML步骤:
①读取并解析XML文档到内存中,形成XML树结构,获得Document对象,Document对象即代表了整个XML文档
SAXReader sax = new SAXReader();
Document document = sax.read(new File(fileName));
②获取根元素
Element root = document.getRootElement();
注:一切XML分析都是从根元素开始的,因为只有获得根元素才能知道其子元素以及后续的内容(XPath技术除外)
③遍历XML树
dom4j提供了至少三种遍历某一节点的方法(如果不通过XPath技术去访问某一指定的节点可以使用根元素导航到元素)
// 枚举所有子节点
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();
// do something
}
// 枚举名称为foo的节点
for ( Iterator i = root.elementIterator(foo); i.hasNext();) {
Element foo = (Element) i.next();
// do something
}
// 枚举属性
for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
Attribute attribute = (Attribute) i.next();
// do something
}
public void treeWalk() {
treeWalk(getRootElement());
}
public void treeWalk(Element element) {
for (int i = 0, size = element.nodeCount(); i < size; i++) {
Node node = element.node(i);
if (node instanceof Element) {
treeWalk((Element) node);
} else { // do something....
}
}
}
常用的Element类下的一些方法(元素本身、元素所含文本内容、元素属性、元素的子元素、元素的父元素)
元素本身的:
getName() 返回元素的名称
getText() 返回元素所含有的text内容,如果内容为空则返回一个空字符串而不是null
属性:
attributeValue(String name) 返回指定名称属性的属性值
子元素:
element(String name) 返回元素的指定名称的子元素
elementText(String name) 返回元素的指定名称的子元素的text内容,相当于element().getText()
elements() 返回该元素下所有的子元素,存储为List。
父元素:
getParent()返回元素的父元素 (多使用在删除该元素操作时)
有两个网站写的不错:
http://www.java3z.com/cwbwebhome/article/article2/2378.html?id=1034
http://www.blogjava.net/i369/articles/154264.html
示例:
public void ParseXML() throws Exception
{
SAXReader sax = new SAXReader();
Document document = sax.read(new File("src/com/qq/xml/learn/FirstXml.xml"));
Element rootElement = document.getRootElement();
@SuppressWarnings("unchecked")
List<Element> studentList = rootElement.elements();
for (Element student : studentList)
{
System.out.println(student.elementText("name")+".." //得到名为name的子元素并将该子元素的内容取出
+student.attributeValue("id")+".." //student元素的属性值
+student.elementText("age")+".."
+student.elementText("score"));
}
}
Document相关(DocumentHelper类):这些都是内存中的。
①解析XML形式的文本,得到document对象。
String text = “<root>根元素</root>”;
Document document = DocumentHelper.parseText(text);
②主动创建XML Document对象
Document document = DocumentHelper.createDocument();
附:
public static void main(String[] args) throws Exception
{
List<Car> carList = new ArrayList<Car>();
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File("src/com/qq/xml/learn/car.xml"));
Element rootElement = document.getRootElement();
List<Element> cars = rootElement.elements();
for (Element car : cars)
{
Car carObj = new Car();
String time = car.element("车牌").attributeValue("出产时间");
String band = car.elementText("车牌");
String place = car.elementText("产地");
int price = Integer.parseInt(car.elementText("单价"));
carObj.setBand(band);
carObj.setTime(time);
carObj.setPlace(place);
carObj.setPrice(price);
carList.add(carObj);
}
System.out.println("未排序-------------");
//未排序前的顺序
show(carList);
System.out.println("排序后-------------");
//排序后的顺序
sortedShow(carList);
}
private static void sortedShow(List<Car> carList)
{
Collections.sort(carList,Collections.reverseOrder(new Comparator<Car>()
{
@Override
public int compare(Car car1, Car car2)
{
return car1.getPrice()-car2.getPrice();
}
}));
show(carList);
}
private static void show(List<Car> carList)
{
if ((carList != null) && (carList.size()>0))
{
for (Car car : carList)
{
System.out.println("车牌:"+car.getBand());
System.out.println("出产时间:"+car.getTime());
System.out.println("产地:"+car.getPlace());
System.out.println("单价:"+car.getPrice());
}
}
}
XPath(一切都是节点,一个节点对应一个元素。并且基于dom4j实现)
使用XPath需要导入jaxen的jar包,该包在dom4j的文件夹内。
XPath即为XML路径语言,它是一种用来确定XML(标准通用标记语言的子集)文档中某部分位置的语言。XPath基于XML的树状结构,提供在数据结构树中找寻节点的。
XPath是用来表达XML文档树各种元素的位置的描述。通过XPath直接获取指定文档元素比较准确,直接,效率也高。
XPath 使用路径表达式在XML中进行导航,相比于直接使用dom4j从根元素导航来得方便。XPath路径分为绝对路径和相对路径。
绝对路径:以”/“开头
相对路径:以”./"开头或元素名开头
路径表达式及其意义:
①bookstore 选取 bookstore 元素的所有子节点。
②/bookstore 选取根元素 bookstore。