XML解析方式之DOM、SAX、JDOM、DOM4J
前端之家收集整理的这篇文章主要介绍了
XML解析方式之DOM、SAX、JDOM、DOM4J,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
一、DOM4J
1、特点:最优秀的一个,集易用和性能于一身。开放源代码(需要导入外部jar包:dom4j-1.6.1.jar)
2、场合:使用DOM4J
|
|
|
Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为,
|
|
CDATA 定义了XML CDATA 区域
|
|
CharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment,Text.
|
|
Comment 定义了XML注释的行为
|
|
定义了XML文档
|
|
DocumentType 定义XML DOCTYPE声明
|
|
Element定义XML 元素
|
|
ElementHandler定义了 Element 对象的处理器
|
|
|
|
Entity定义 XML entity
|
|
Node为所有的dom4j中XML节点定义了多态行为
|
|
NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)
|
|
ProcessingInstruction 定义 XML 处理指令.
|
|
Text 定义XML 文本节点.
|
|
Visitor 用于实现Visitor模式.
|
|
XPath 在分析一个字符串后会提供一个XPath 表达式
|
- SAXReaderreader=newSAXReader();Documentdoc=reader.read(Filexmlfile);
- ListchildNodes=doc.selectNodes("//Config/Child/ChildNode");
- for(Objectobj:childNodes){
- NodechildNode=(Node)obj;
- Stringname=childNode.valueOf("@name");
- Stringtext=childNode.getText();
- }
- 一.Document对象相关
- 1.读取XML文件,获得document对象.
- SAXReaderreader=newSAXReader();
- Documentdocument=reader.read(newFile("input.xml"));
- 2.解析XML形式的文本,得到document对象.
- Stringtext="<members></members>";
- Documentdocument=DocumentHelper.parseText(text);
- 3.主动创建document对象.
- Documentdocument=DocumentHelper.createDocument();
- Elementroot=document.addElement("members");
- 二.节点相关
- 1.获取文档的根节点.
- ElementrootElm=document.getRootElement();
- 2.取得某节点的单个子节点.
- ElementmemberElm=root.element("member");
- 3.取得节点的文字
- Stringtext=memberElm.getText();也可以用:
- Stringtext=root.elementText("name");这个是取得根节点下的name字节点的文字.
- 4.取得某节点下名为"member"的所有字节点并进行遍历.
- Listnodes=rootElm.elements("member");
- for(Iteratorit=nodes.iterator();it.hasNext();){
- Elementelm=(Element)it.next();
-
- 5.对某节点下的所有子节点进行遍历.
- for(Iteratorit=root.elementIterator();it.hasNext();){
- Elementelement=(Element)it.next();
-
- }
- 6.在某节点下添加子节点.
- ElementageElm=newMemberElm.addElement("age");
- 7.设置节点文字.
- ageElm.setText("29");
- 8.删除某节点.
- parentElm.remove(childElm);
- 9.添加一个CDATA节点.
- ElementcontentElm=infoElm.addElement("content");
- contentElm.addCDATA(diary.getContent());
-
- 三.属性相关.
- 1.取得某节点下的某属性
- Elementroot=document.getRootElement();
- Attributeattribute=root.attribute("size");
- 2.取得属性的文字
- Stringtext=attribute.getText();也可以用:
- Stringtext2=root.element("name").attributeValue("firstname");这个是取得根节点下name字节点的属性firstname的值.
- 3.遍历某节点的所有属性
- for(Iteratorit=root.attributeIterator();it.hasNext();){
- Attributeattribute=(Attribute)it.next();
- Stringtext=attribute.getText();
- System.out.println(text);
- 4.设置某节点的属性和文字.
- newMemberElm.addAttribute("name","sitinspring");
- 5.设置属性的文字
- Attributeattribute=root.attribute("name");
- attribute.setText("sitinspring");
- 6.删除某属性
- Attributeattribute=root.attribute("size");
- root.remove(attribute);
- 四.将文档写入XML文件.
- 1.文档中全为英文,不设置编码,直接写入的形式.
- XMLWriterwriter=newXMLWriter(newFileWriter("output.xml"));
- writer.write(document);
- writer.close();
- 2.文档中含有中文,设置编码格式写入的形式.(或以美化的格式输出到文件)
- OutputFormatformat=OutputFormat.createPrettyPrint();
- format.setEncoding("GBK");
- XMLWriterwriter=newXMLWriter(newFileWriter("output.xml"),format);
- 五.字符串与XML的转换
- 1.将字符串转化为XML
- Stringtext="<members><member>sitinspring</member></members>";
- Documentdocument=DocumentHelper.parseText(text);
- 2.将文档或节点的XML转化为字符串.
- SAXReaderreader=newSAXReader();
- Documentdocument=reader.read(newFile("input.xml"));
- StringdocXmlText=document.asXML();
- StringrootXmlText=root.asXML();
- ElementmemberElm=root.element("member");
- StringmemberXmlText=memberElm.asXML();
- dom4jAPI包含一个解析XML文档的工具。本文中将使用这个解析器创建一个示例XML文档。清单1显示了这个示例XML文档,catalog.xml。
- 与W3CDOMAPI相比,使用dom4j所包含的解析器的好处是dom4j拥有本地的XPath支持。DOM解析器不支持使用XPath选择节点。
?
/*DOM4J提供至少3种遍历节点的方法*/
- //1)枚举(Iterator)
- //枚举所有子节点
- for(Iteratori=root.elementIterator();i.hasNext();){
- Elementelement=(Element)i.next();
- //枚举名称为foo的节点
- for(Iteratori=root.elementIterator(foo);i.hasNext();){
- Elementfoo=(Element)i.next();
- //枚举属性
- for(Iteratori=root.attributeIterator();i.hasNext();){
- Attributeattribute=(Attribute)i.next();
- //2)递归
- //递归也可以采用Iterator作为枚举手段,但文档中提供了另外的做法
- publicvoidtreeWalk(){
- treeWalk(getRootElement());
- publicvoidtreeWalk(Elementelement){
- for(inti=0,size=element.nodeCount();i<size;i++){
- Nodenode=element.node(i);
- if(nodeinstanceofElement){
- treeWalk((Element)node);
- }else{
- //3)Visitor模式
- //主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多Visitable。只需要自定一个类实现Visitor接口即可。
- publicclassMyVisitorextendsVisitorSupport{
- publicvoidvisit(Elementelement){
- System.out.println(element.getName());
- publicvoidvisit(Attributeattr){
- System.out.println(attr.getName());
- //调用:root.accept(newMyVisitor())
importjava.io.File;
- importjava.io.FileWriter;
- importjava.io.IOException;
- importjava.util.Iterator;
- importorg.dom4j.Attribute;
- importorg.dom4j.Document;
- importorg.dom4j.DocumentException;
- importorg.dom4j.DocumentHelper;
- importorg.dom4j.Element;
- importorg.dom4j.io.SAXReader;
- importorg.dom4j.io.XMLWriter;
- /**
- *dom4j生成与解析XML文档
- */
- publicclassDom4jDemo{
-
- /**
- *利用dom4j进行xml文档的写入操作
- */
- publicvoidcreateXml(Filefile){
- //XML声明<?xmlversion="1.0"encoding="UTF-8"?>自动添加到XML文档中
- //使用DocumentHelper类创建文档实例(生成XML文档节点的dom4jAPI工厂类)
- //使用addElement()方法创建根元素employees(用于向XML文档中增加元素)
- Elementroot=document.addElement("employees");
- //在根元素中使用addComment()方法添加注释"AnXMLNote"
- root.addComment("AnXMLNote");
- //在根元素中使用addProcessingInstruction()方法增加一个处理指令
- root.addProcessingInstruction("target","text");
- //在根元素中使用addElement()方法增加employee元素。
- ElementempElem=root.addElement("employee");
- //使用addAttribute()方法向employee元素添加id和name属性
- empElem.addAttribute("id","0001");
- empElem.addAttribute("name","wanglp");
- //向employee元素中添加sex元素
- ElementsexElem=empElem.addElement("sex");
- //使用setText()方法设置sex元素的文本
- sexElem.setText("m");
- //在employee元素中增加age元素并设置该元素的文本。
- ElementageElem=empElem.addElement("age");
- ageElem.setText("25");
- Elementemp2Elem=root.addElement("employee");
- emp2Elem.addAttribute("id","0002");
- emp2Elem.addAttribute("name","fox");
- Elementsex2Elem=emp2Elem.addElement("sex");
- sex2Elem.setText("f");
- Elementage2Elem=emp2Elem.addElement("age");
- age2Elem.setText("24");
- //可以使用addDoctype()方法添加文档类型说明。
- //document.addDocType("employees",null,"file://E:/Dtds/dom4j.dtd");
- //这样就向XML文档中增加文档类型说明:
- //<!DOCTYPEemployeesSYSTEM"file://E:/Dtds/dom4j.dtd">
- //如果文档要使用文档类型定义(DTD)文档验证则必须有Doctype。
- try{
- XMLWriteroutput=newXMLWriter(newFileWriter(file));
- output.write(document);
- output.close();
- }catch(IOExceptione){
- System.out.println(e.getMessage());
- *利用dom4j进行xml文档的读取操作
- publicvoidparserXml(Filefile){
- Documentdocument=null;
- //使用SAXReader解析XML文档catalog.xml:
- SAXReadersaxReader=newSAXReader();
- try{
- document=saxReader.read(file);
- }catch(DocumentExceptione){
- e.printStackTrace();
- //将字符串转为XML
- //document=DocumentHelper.parseText(fileString);
- //获取根节点
- //打印节点名称
- System.out.println("<"+root.getName()+">");
- //获取根节点下的子节点遍历
- Iterator<?>iter=root.elementIterator("employee");
- //遍历employee节点
- while(iter.hasNext()){
- //获取当前子节点
- ElementempEle=(Element)iter.next();
- System.out.println("<"+empEle.getName()+">");
- //获取当前子节点的属性遍历
- Iterator<?>attrList=empEle.attributeIterator();
- while(attrList.hasNext()){
- Attributeattr=(Attribute)attrList.next();
- System.out.println(attr.getName()+"="+attr.getValue());
- //遍历employee节点下所有子节点
- Iterator<?>eleIte=empEle.elementIterator();
- while(eleIte.hasNext()){
- Elementele=(Element)eleIte.next();
- System.out.println("<"+ele.getName()+">"+ele.getTextTrim());
- //获取employee节点下的子节点sex值
- //Stringsex=empEle.elementTextTrim("sex");
- //System.out.println("sex:"+sex);
- System.out.println("</"+root.getName()+">");
- publicstaticvoidmain(String[]args){
- Dom4jDemodom4j=newDom4jDemo();
- Filefile=newFile("e:/dom4j.xml");
- //dom4j.createXml(file);
- dom4j.parserXml(file);
- }
/*修改xml文档*/
- publicstaticvoidmodifyxml(){
- //使用SAXReader去解析xml文件
- SAXReaderreader=newSAXReader();
- Documentdocument;
- try{
- Filefile=newFile("C:\\workspace\\Test\\myxml.xml");
- //获取document对象
- document=reader.read(file);
- //通过selectNodes寻找节点或者属性
- Listlist=document.selectNodes("/student/call/@show");
- Iteratorit=list.iterator();
- while(it.hasNext()){
- //Attribute属性的操作方法
- Attributeattribute=(Attribute)it.next();
- if(attribute.getValue().equals("yes"))
- {
-
- attribute.setValue("no");
- }
- }
- list=document.selectNodes("/student/call/name");
- it=list.iterator();
- while(it.hasNext()){
- //标签内容的操作方法
- ElementnameElment=(Element)it.next();
- nameElment.setText("studentname");
- //删除某个节点是要用两层循环,因为删除当前节点必须用父节点去删除。
- list=document.selectNodes("/student/call");
- //获取父节点
- ElementscoreElement=(Element)it.next();
- System.out.println(scoreElement);
- @SuppressWarnings("unused")
- //获取该父节点下面的需要查找的子节点
- Iteratoritera=scoreElement.elementIterator("English");
- while(itera.hasNext()){
- ElementscoreEnglish=(Element)itera.next();
- if(scoreEnglish.getText().equals("77")){
- //利用父节点去删除
- scoreElement.remove(scoreEnglish);
- @SuppressWarnings("unused")
- /*Iteratoritera=document.getRootElement().elementIterator("call");
- Elementele=(Element)itera.next();
- System.out.println(ele);
- }*/
-
- OutputFormatformat=OutputFormat.createPrettyPrint();
- format.setEncoding("UTF-8");
- XMLWriterwriter;
- try{
- writer=newXMLWriter(newFileWriter("myxml.xml"),format);
- writer.write(document);
- writer.close();
- }catch(IOExceptione){
- e.printStackTrace();
- }catch(DocumentExceptione){
- }
二、JDOM
1、原理:纯Java的处理XML的API,要实现的功能简单,如解析、创建等,但在底层,JDOM还是使
用SAX、DOM、Xanan文档。(需要导入外部jar包:jdom.jar)
2、优点:a、是基于树的处理XML的Java API,把树加载在内存中,具有DOM方式的优点。
b、没有向下兼容的限制,因此比DOM简单
c、可速度快,缺陷少
d、具有SAX的JAVA规则
3、 缺点:a、不能处理大于内存的文档。Dom方式的缺点
b、JDOM表示XML文档逻辑模型。不能保证每个字节真正变换。
c、针对实例文档不提供DTD与模式的任何实际模型。
d、
不支持与DOM中相应遍历包
4、场合:在需要平衡时使用。JDOM具有树的便利,也有SAX的JAVA规则。
//导入jar包:jdom.jarimportjava.io.File;
- importjava.io.FileNotFoundException;
- importjava.io.FileOutputStream;
- importjava.io.IOException;
- importjava.util.List;
- importorg.jdom.Attribute;
- importorg.jdom.Comment;
- importorg.jdom.Document;
- importorg.jdom.Element;
- importorg.jdom.JDOMException;
- importorg.jdom.input.SAXBuilder;
- importorg.jdom.output.Format;
- importorg.jdom.output.XMLOutputter;
- *jdom生成与解析XML文档
- publicclassJdomDemo{
- Documentdocument=newDocument();
- *利用JDom进行xml文档的写入操作
- //1.创建元素及设置为根元素
- Elementemployees=newElement("employees");
- document.setContent(employees);
- //2.创建注释及设置到根元素上
- Commentcommet=newComment("thisismycomment");
- employees.addContent(commet);
- //3.创建元素
- Elementelement1=newElement("employee");
- //3.1设置元素的属性名及属性值
- element1.setAttribute(newAttribute("id","0001"));
- //3.2创建元素的属性名及属性值
- AttributenameAttr=newAttribute("name",0); background-color:inherit">//3.3设置元素名及文本
- ElementsexEle=newElement("sex");
- sexEle.setText("m");
- //设置到上层元素上
- element1.addContent(sexEle);
- //设置元素
- ElementageEle=newElement("age");
- ageEle.setText("22");
- element1.addContent(ageEle);
- //设置为根元素的子元素
- employees.addContent(element1);
- //将元素属性设置到元素上
- element1.setAttribute(nameAttr);
- //3.创建元素
- Elementelement2=newElement("employee");
- //3.1设置元素的属性名及属性值
- element2.setAttribute(newAttribute("id","0002"));
- //3.2创建元素的属性名及属性值
- Attributename2Attr=newAttribute("name","fox");
- //3.3设置元素名及文本
- Elementsex2Ele=newElement("sex");
- sex2Ele.setText("f");
- //设置到上层元素上
- element2.addContent(sex2Ele);
- //设置元素
- Elementage2Ele=newElement("age");
- age2Ele.setText("21");
- element2.addContent(age2Ele);
- //设置为根元素的子元素
- employees.addContent(element2);
- //将元素属性设置到元素上
- element2.setAttribute(name2Attr);
- Elementelement3=newElement("employee");
- element3.setText("title");
- element3.addContent(newElement("name").addContent(newElement("hello")));
- employees.addContent(element3);
- //设置xml文档输出的格式
- Formatformat=Format.getPrettyFormat();
- XMLOutputterout=newXMLOutputter(format);
- //将得到的xml文档输出到文件流中
- out.output(document,newFileOutputStream(file));
- }catch(FileNotFoundExceptione){
- }catch(IOExceptione){
- *利用JDom进行xml文档的读取操作
- publicvoidparserXml(Filefile){
- //建立解析器
- SAXBuilderbuilder=newSAXBuilder();
- //将解析器与文档关联
- document=builder.build(file);
- }catch(JDOMExceptione1){
- e1.printStackTrace();
- }catch(IOExceptione1){
- //读取根元素
- Elementroot=document.getRootElement();
- //输出根元素的名字
- System.out.println("<"+root.getName()+">");
- //读取元素集合
- List<?>employeeList=root.getChildren("employee");
- 0;i<employeeList.size();i++){
- Elementele=(Element)employeeList.get(i);
- //得到元素的名字
- System.out.println("<"+ele.getName()+">");
- //读取元素的属性集合
- List<?>empAttrList=ele.getAttributes();
- for(intj=0;j<empAttrList.size();j++){
- Attributeattrs=(Attribute)empAttrList.get(j);
- //将属性的名字和值并输出
- Stringname=attrs.getName();
- Stringvalue=(String)attrs.getValue();
- System.out.println(name+"="+value);
- Elementsex=ele.getChild("sex");
- System.out.println("<sex>"+sex.getText());
- Elementage=ele.getChild("age");
- System.out.println("<age>"+age.getText());
- }catch(NullPointerExceptione){
- System.out.println(ele.getTextTrim());
- Elementname=ele.getChild("name");
- System.out.println("<name>"+name.getName());
- System.out.println("</employee>");
- System.out.println("</employees>");
- *测试
- publicstaticvoidmain(String[]args){
- JdomDemojdom=newJdomDemo();
- Filefile=newFile("E://jdom.xml");
- jdom.createXml(file);
- jdom.parserXml(file);
- 三、DOM
1、原理:DOM是基于树的结构,解析器读入-整个-文档,然后构建一个驻留内存的树结构,使用 DOM 接 口来操作这个树结构。
2、优点:a、由于整棵树在内存中,便于操作,可以对xml文档随机访问
b、可以对xml文档进行删除、修改、重新排列等多种功能;访问效率高
c、较sax,dom使用也更简单。
3、缺点:a、整个文档必须一次性解析完(无用的节点也会解析),浪费时间和空间.
b、由于整个文档都需要载入内存,对于大文档成本高
4、 场合:小型xml文档;一旦解析了文档还需多次访问这些数据;
?
importjava.io.PrintWriter;
- importjavax.xml.parsers.DocumentBuilder;
- importjavax.xml.parsers.DocumentBuilderFactory;
- importjavax.xml.parsers.ParserConfigurationException;
- importjavax.xml.transform.OutputKeys;
- importjavax.xml.transform.Transformer;
- importjavax.xml.transform.TransformerConfigurationException;
- importjavax.xml.transform.TransformerException;
- importjavax.xml.transform.TransformerFactory;
- importjavax.xml.transform.dom.DOMSource;
- importjavax.xml.transform.stream.StreamResult;
- importorg.w3c.dom.Attr;
- importorg.w3c.dom.Document;
- importorg.w3c.dom.Element;
- importorg.w3c.dom.Node;
- importorg.w3c.dom.NodeList;
- importorg.xml.sax.SAXException;
- *DOM生成与解析XML文档
- *
- *@author莫小哆_ly2012-2-20
- publicclassDomDemo{
- /*
- *解析器读入整个文档,然后构建一个驻留内存的树结构,
- *
- *然后代码就可以使用DOM接口来操作这个树结构。
- *优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
- *缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
- *使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、cpu)
- //表示整个HTML或XML文档。从概念上讲,它是文档树的根,并提供对文档数据的基本访问
- privateDocumentdocument;
- *创建DOM树
- *要读入一个XML文档,首先要一个DocumentBuilder对象
- publicvoidinit(){
- //获取DocumentBuilderFactory的新实例
- DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();
- //使用当前配置的参数创建一个新的DocumentBuilder实例
- DocumentBuilderbuilder=null;
- builder=factory.newDocumentBuilder();
- }catch(ParserConfigurationExceptione){
- e.printStackTrace();
- //获取DOMDocument对象的一个新实例来生成一个DOM树
- this.document=builder.newDocument();
- *xml文档的写入操作
- *@paramfile
- //创建DOM树
- this.init();
- //创建XML根节点employees
- Elementroot=this.document.createElement("employees");
- //AddsthenodenewChildtotheendofthelistofchildrenofthis
- //node.
- //IfthenewChildisalreadyinthetree,itisfirstremoved.
- this.document.appendChild(root);
- //1.创建根节点的子节点employee
- Elementemployee=this.document.createElement("employee");
- //向根节点添加属性节点
- Attrid=this.document.createAttribute("id");
- id.setNodeValue("0001");
- //把属性节点对象,追加到达employee节点;
- employee.setAttributeNode(id);
- //声明employee的子节点name
- Elementname=this.document.createElement("name");
- //向XML文件name节点追加数据
- name.appendChild(this.document.createTextNode("wanglp"));
- //把子节点的属性追加到employee子节点中元素中
- employee.appendChild(name);
- //声明employee的子节点sex
- Elementsex=this.document.createElement("sex");
- //向XML文件sex节点追加数据
- sex.appendChild(this.document.createTextNode("m"));
- //把子节点的属性追加到employee子节点中元素中
- employee.appendChild(sex);
- //声明employee的子节点age
- Elementage=this.document.createElement("age");
- //向XML文件age节点追加数据
- age.appendChild(this.document.createTextNode("25"));
- employee.appendChild(age);
- //employee节点定义完成,追加到root
- root.appendChild(employee);
- //2.创建根节点的子节点employee
- employee=this.document.createElement("employee");
- //向根节点添加属性节点
- id=this.document.createAttribute("id");
- id.setNodeValue("0002");
- //把属性节点对象,追加到达employee节点;
- employee.setAttributeNode(id);
- //声明employee的子节点name
- name=this.document.createElement("name");
- //向XML文件name节点追加数据
- name.appendChild(this.document.createTextNode("huli"));
- employee.appendChild(name);
- //声明employee的子节点sex
- sex=this.document.createElement("sex");
- //向XML文件sex节点追加数据
- sex.appendChild(this.document.createTextNode("f"));
- employee.appendChild(sex);
- //声明employee的子节点age
- age=this.document.createElement("age");
- //向XML文件age节点追加数据
- age.appendChild(this.document.createTextNode("12"));
- employee.appendChild(age);
- //employee节点定义完成,追加到root
- root.appendChild(employee);
- //获取TransformerFactory的新实例。
- TransformerFactorytf=TransformerFactory.newInstance();
- //创建执行从Source到Result的复制的新Transformer。能够将源树转换为结果树
- Transformertransformer=null;
- transformer=tf.newTransformer();
- }catch(TransformerConfigurationExceptione){
- //设置转换中实际的输出属性
- //指定首选的字符编码
- transformer.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
- //indent="yes"|"no".指定了当输出结果树时,Transformer是否可以添加额外的空白
- transformer.setOutputProperty(OutputKeys.INDENT,"yes");
- //声明文件流
- PrintWriterpw=null;
- pw=newPrintWriter(newFileOutputStream(file));
- System.out.println("文件没有找到!");
- //充当转换结果的持有者,可以为XML、纯文本、HTML或某些其他格式的标记
- StreamResultresult=newStreamResult(pw);
- //DOMSourceimplementsSource
- DOMSourcesource=newDOMSource(document);
- //将XMLSource转换为Result
- transformer.transform(source,result);
- }catch(TransformerExceptione){
- System.out.println("生成XML文件失败!");
- System.out.println("生成XML文件成功!");
- *xml文档的读取操作
- DocumentBuilderbuilder;
- //将给定URI的内容解析为一个XML文档,并且返回一个新的DOMDocument对象
- document=builder.parse(file);
- }catch(SAXExceptione){
- //获得文档根元素对对象;
- Elementroot=document.getDocumentElement();
- //获得文档根元素下一级子元素所有元素;
- NodeListnodeList=root.getChildNodes();
- System.out.print("<employees>");
- System.out.println(root.getNodeName());
- if(null!=root){
- for(inti=0;i<nodeList.getLength();i++){
- Nodechild=nodeList.item(i);
- //输出child的属性;
- System.out.print("<test>");
- System.out.println(child);
- if(child.getNodeType()==Node.ELEMENT_NODE){
- System.out.print("<id>");
- System.out.println(child.getAttributes().getNamedItem("id").getNodeValue());
- for(Nodenode=child.getFirstChild();node!=null;node=node.getNextSibling()){
- if(node.getNodeType()==Node.ELEMENT_NODE){
- if("name".equals(node.getNodeName())){
- System.out.print("<name>");
- System.out.println(node.getFirstChild().getNodeValue());
- if("sex".equals(node.getNodeName())){
- System.out.print("<sex>");
- if("age".equals(node.getNodeName())){
- System.out.print("<age>");
- if("email".equals(node.getNodeName())){
- System.out.print("<email>");
- System.out.println("解析完毕");
- *测试
- //为什么有类似于这样东西[#text:]
- //原因是XML文件元素之间的空白字符也是一个元素,<employees></employees>包含的空白
- DomDemodom=newDomDemo();
- Filefile=newFile("E://dom.xml");
- dom.createXml(file);
- dom.parserXml(file);
- 四、SAX
1、原理:SAX类似流媒体,它基于事件驱动,当解析器发现元素开始、元素结束、文本、文档的开始或结束 等时,发送事件,程序员编写响应这些事件的代码,保存数据。无需将整个文档载入内存,使用者 只需要监听自己感兴趣的事件即可。
2、优点:a、无需将整个xml文档载入内存,因此消耗内存少
b、SAX解析器代码比DOM解析器代码小,适于Applet,下载。
c、可以注册多个ContentHandler
3、缺点:a、不能随机的访问xml中的节点
b、只支持读,不能修改文档。非持久,事件过后,若没保存数据,那么数据就丢了
c、无状态性;从事件中只能得到文本,但不知该文本属于哪个元素
4、场合:大型xml文档;Applet;只需XML文档的少量内容,很少回头访问;
?
importjavax.xml.parsers.SAXParser;
- importjavax.xml.parsers.SAXParserFactory;
- importorg.xml.sax.Attributes;
- importorg.xml.sax.helpers.DefaultHandler;
- *startDocument(),endDocument(),startElement(),endElement(),characters()
- publicclassSAXParseDemoextendsDefaultHandler{
- privateStringtagValue;
- //开始解析XML文件
- publicvoidstartDocument()throwsSAXException{
- System.out.println("开始解析");
- //结束解析XML文件
- publicvoidendDocument()throwsSAXException{
- System.out.println("结束解析");
- //解析元素
- *开始解析一个元素
- *@paramqName标签名
- *@paramattributes属性
- @Override
- publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesattributes)
- throwsSAXException{
- System.out.println(qName+"开始");
- //属性
- if(attributes!=null&&attributes.getLength()!=0){
- System.out.println("属性:");
- 0;i<attributes.getLength();i++){
- System.out.print(attributes.getQName(i)+"=");
- System.out.print(attributes.getValue(i)+"");
- System.out.println();
- *结束一个元素的解析遇到结束标签时调用此方法通常在此方法对标签取值并处理
- publicvoidendElement(Stringuri,StringqName)throwsSAXException{
- System.out.println(qName+"标签值:"+tagValue);
- System.out.println(qName+"结束");
- //所有xml文件中的字符都会放到ch[]中
- publicvoidcharacters(charch[],intstart,intlength)throwsSAXException{
- tagValue=newString(ch,start,length).trim();
- Filefile=newFile("src/cn/main/example/demo.xml");
- SAXParserFactorysaxParFac=SAXParserFactory.newInstance();
- SAXParsersaxParser=saxParFac.newSAXParser();
- saxParser.parse(file,newSAXParseDemo());
- }catch(Exceptione){
- }
五、资料(关于Xpath)
1、选取节点
XPath 使用路径表达式在 XML 文档中选取节点,节点是沿着路径或者 step 来选取的。
常见的路径表达式:
表达式 |
描述 |
nodename |
选取当前节点的所有子节点 |
/ |
从根节点选取 |
// |
从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. |
选取当前节点 |
.. |
选取当前节点的父节点 |
@ |
选取属性 |
实例
路径表达式
结果 |
bookstore |
选取 bookstore 元素的所有子节点 |
/bookstore |
选取根元素 bookstore |
bookstore/book |
选取bookstore 下名字为 book的所有子元素。 |
//book |
选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book |
选取bookstore 下名字为 book的所有后代元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang |
选取所有名为 lang 的属性。 |
2、谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
实例
常见的谓语的一些路径表达式:
/bookstore/book[1]
选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] |
选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] |
选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] |
选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] |
选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang='eng'] |
选取所有 title 元素,要求这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] |
选取所有 bookstore 元素的 book 元素,要求book元素的子元素 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title |
选取所有 bookstore 元素中的 book 元素的 title 元素,要求book元素的子元素 price 元素的值须大于 35.00 |
3、选取未知节点
XPath 通配符可用来选取未知的 XML 元素。
通配符
* |
匹配任何元素节点 |
@* |
匹配任何属性节点 |
node() |
匹配任何类型的节点 |
/bookstore/*
//* |
选取文档中的所有元素 |
//title[@*] |
选取所有带有属性的 title 元素。 |
4、选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。
路径表达式 |
@H_688_5027@ 结果
//book/title|//book/price |
@H_688_5027@ 选取所有 book 元素的 title 和 price 元素。
//title|//price |
@H_688_5027@ 选取所有文档中的 title 和 price 元素。
/bookstore/book/title|//price |
@H_688_5027@ 选取所有属于 bookstore 元素的 book 元素的 title 元素,以及文档中所有的 price 元素。
5、XPath 轴
轴可定义某个相对于当前节点的节点集。
轴名称
ancestor |
选取当前节点的所有先辈(父、祖父等) |
ancestor-or-self |
选取当前节点的所有先辈(父、祖父等)以及当前节点本身 |
attribute |
选取当前节点的所有属性 |
child |
选取当前节点的所有子元素。 |
descendant |
选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self |
选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following |
选取文档中当前节点的结束标签之后的所有节点。 |
namespace |
选取当前节点的所有命名空间节点 |
parent |
选取当前节点的父节点。 |
preceding |
选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling |
选取当前节点之前的所有同级节点。 |
self |
选取当前节点。 |
6、路径
位置路径可以是绝对的,也可以是相对的。
绝对路径起始于正斜杠( / ),而相对路径不会这样。在两种情况中,位置路径均包括一个或多个步,每个步均被斜杠分割:
/step/step/...
step/step/...
每个步均根据当前节点集之中的节点来进行计算。
轴(axis):定义所选节点与当前节点之间的树关系
节点测试(node-test):识别某个轴内部的节点
零个或者更多谓语(predicate):更深入地提炼所选的节点集
步的语法:轴名称::节点测试[谓语]
例子
child::book |
选取所有属于当前节点的子元素的 book 节点 |
attribute::lang |
选取当前节点的 lang 属性 |
child::* |
选取当前节点的所有子元素 |
attribute::* |
child::text() |
选取当前节点的所有文本子节点 |
child::node() |
descendant::book |
选取当前节点的所有 book 后代 |
ancestor::book |
选择当前节点的所有 book 先辈 |
ancestor-or-self::book |
选取当前节点的所有book先辈以及当前节点(假如此节点是book节点的话) |
child::*/child::price |
选取当前节点的所有 price 孙。 |
7、XPath 运算符
运算符 |
描述 |
实例 |
返回值 |
| |
计算两个节点集 |
//book | //cd |
返回所有带有 book 和 ck 元素的节点集 |
+ |
加法 |
6 + 4 |
10 |
- |
减法 |
6 - 4 |
2 |
* |
乘法 |
6 * 4 |
24 |
div |
除法 |
8 div 4 |
= |
等于 |
price=9.80 |
如果 price 是 9.80,则返回 true。 如果 price 是 9.90,则返回 fasle。 |
!= |
不等于 |
price!=9.80 |
如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 fasle。 |
< |
小于 |
price<9.80 |
如果 price 是 9.00,则返回 true。 如果 price 是 9.90,则返回 fasle。 |
<= |
小于或等于 |
price<=9.80 |
> |
大于 |
price>9.80 |
>= |
大于或等于 |
price>=9.80 |
如果 price 是 9.90,则返回 true。 如果 price 是 9.70,则返回 fasle。 |
or |
或 |
price=9.80 or price=9.70 |
如果 price 是 9.80,则返回 true。 如果 price 是 9.50,则返回 fasle。 |
and |
与 |
price>9.00 and price<9.90 |
如果 price 是 9.80,则返回 true。 如果 price 是 8.50,则返回 fasle。 |
mod |
计算除法的余数 |
5 mod 2 |
1 |
大部分源代码来源于:http://www.jb51.cc/article/p-poqlaaev-bdz.html
部分资料来源于:http://www.jb51.cc/article/p-gkrkxlnq-ck.html
Dom4j大部分资料来源于:http://www.jb51.cc/article/p-atlhkbmf-bhz.html
Xpath部分内容来源于:http://nemogu.iteye.com/blog/1305503