xml现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。对于xml本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有dom(document object model),dtd(document type definition),sax(simple api for xml),xsd(xml schema definition),xslt(extensible stylesheet language transformations),具体可参阅w3c官方网站文档获取更多信息。
xml在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种叫sax,另一种叫dom。sax是基于事件流的解析,dom是基于xml文档树结构的解析。假设我们xml的内容和结构如下:
<?xml version="1.0" encoding="utf-8"?><employees><employee> <name>ddviplinux</name> <sex>m</sex> <age>30</age></employee></employees>
本文使用java语言来实现dom与sax的xml文档生成与解析。
首先定义一个操作xml文档的接口xmldocument 它定义了xml文档的建立与解析的接口。
package com.beyond.framework.bean; /** * @author zhengwei * 定义xml文档建立与解析的接口 */ public interface xmldocument { /** * 建立xml文档 * @param filename 文件全路径名称 */ public void createxml(string filename); /** * 解析xml文档 * @param filename 文件全路径名称 */ public void parserxml(string filename); }
1. dom生成和解析xml文档
为 xml 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 dom 接口来操作这个树结构。
优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;
缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;
使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、cpu)。
domdemo ==.document = = .document.createelement(employees= .document.createelement(employee= .document.createelement(name.document.createtextnode(丁宏亮= .document.createelement(sex.document.createtextnode(m= .document.createelement(age.document.createtextnode(30=== gb2312yes= printwriter(= 生成xml文件成功! ==== ( i = 0; i < employees.getlength(); i++== ( j = 0; j < employeeinfo.getlength(); j++== ( k = 0; k < employeemeta.getlength(); k+++ ":" +"解析完毕"
2. sax生成和解析xml文档
为解决dom的问题,出现了sax。sax ,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。
优点:不用事先调入整个文档,占用资源少;sax解析器代码比dom解析器代码小,适于applet,下载。
缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素;
使用场合:applet;只需xml文档的少量内容,很少回头访问;机器内存少;
import java.io.fileinputstream;import java.io.filenotfoundexception;import java.io.ioexception;import java.io.inputstream;import javax.xml.parsers.parserconfigurationexception;import javax.xml.parsers.saxparser;import javax.xml.parsers.saxparserfactory;import org.xml.sax.attributes;import org.xml.sax.saxexception;import org.xml.sax.helpers.defaulthandler;/*** @author zhengwei * sax文档解析*/public class saxdemo implements xmldocument { public void createxml(string filename) { system.out.println("<<"+filename+">>); } public void parserxml(string filename) { saxparserfactory saxfac = saxparserfactory.newinstance(); try { saxparser saxparser = saxfac.newsaxparser(); inputstream is = new fileinputstream(filename); saxparser.parse(is, new mysaxhandler()); } catch (parserconfigurationexception e) { e.printstacktrace(); } catch (saxexception e) { e.printstacktrace(); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } } } class mysaxhandler extends defaulthandler { boolean hasattribute = false; attributes attributes = null; public void startdocument() throws saxexception { system.out.println(文档开始打印了); } public void enddocument() throws saxexception { system.out.println(文档打印结束了); } public void startelement(string uri, string localname, string qname, attributes attributes) throws saxexception { if (qname.equals(employees)) { return; } if (qname.equals(employee)) { system.out.println(qname); } if (attributes.getlength() > 0) { this.attributes = attributes; this.hasattribute = true; } } public void endelement(string uri, string localname, string qname) throws saxexception { if (hasattribute && (attributes != null)) { for (int i = 0; i < attributes.getlength(); i++) { system.out.println(attributes.getqname(0) + attributes.getvalue(0)); } } } public void characters(char[] ch, int start, int length) throws saxexception { system.out.println(new string(ch, start, length)); } }
3. dom4j生成和解析xml文档
dom4j 是一个非常非常优秀的java xml api,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 java 软件都在使用 dom4j 来读写 xml,特别值得一提的是连 sun 的 jaxm 也在用 dom4j。
import java.io.file; import java.io.filewriter; import java.io.ioexception; import java.io.writer; import java.util.iterator; import org.dom4j.document; import org.dom4j.documentexception; import org.dom4j.documenthelper; import org.dom4j.element; import org.dom4j.io.saxreader; import org.dom4j.io.xmlwriter; /** * @author zhengwei * dom4j 生成xml文档与解析xml文档 */ public class dom4jdemo implements xmldocument { public void createxml(string filename) { document document = documenthelper.createdocument(); element employees=document.addelement(employees); element employee=employees.addelement(employee); element name= employee.addelement(name); name.settext(ddvip); element sex=employee.addelement(sex); sex.settext(m); element age=employee.addelement(age); age.settext(29); try { writer filewriter=new filewriter(filename); xmlwriter xmlwriter=new xmlwriter(filewriter); xmlwriter.write(document); xmlwriter.close(); } catch (ioexception e) { system.out.println(e.getmessage()); } } public void parserxml(string filename) { file inputxml=new file(filename); saxreader saxreader = new saxreader(); try { document document = saxreader.read(inputxml); element employees=document.getrootelement(); for(iterator i = employees.elementiterator(); i.hasnext();){ element employee = (element) i.next();for(iterator j = employee.elementiterator(); j.hasnext();){ element node=(element) j.next(); system.out.println(node.getname()+:+node.gettext()); } } } catch (documentexception e) { system.out.println(e.getmessage()); } system.out.println(dom4j parserxml); } }
4. jdom生成和解析xml
为减少dom、sax的编码量,出现了jdom;
优点:20-80原则,极大减少了代码量。
使用场合:要实现的功能简单,如解析、创建等,但在底层,jdom还是使用sax(最常用)、dom、xanan文档。
import java.io.filenotfoundexception; import java.io.fileoutputstream; import java.io.ioexception; import java.util.list; import org.jdom.document; import org.jdom.element; import org.jdom.jdomexception; import org.jdom.input.saxbuilder; import org.jdom.output.xmloutputter; /*** @author zhengwei * jdom 生成与解析xml文档 */ public class jdomdemo implements xmldocument { public void createxml(string filename) { document document; element root; root=new element(employees); document=new document(root); element employee=new element(employee); root.addcontent(employee); element name=new element(name); name.settext(ddvip); employee.addcontent(name); element sex=new element(sex); sex.settext(m); employee.addcontent(sex); element age=new element(age); age.settext(23); employee.addcontent(age); xmloutputter xmlout = new xmloutputter(); try { xmlout.output(document, new fileoutputstream(filename)); } catch (filenotfoundexception e) { e.printstacktrace(); } catch (ioexception e) { e.printstacktrace(); } }public void parserxml(string filename) { saxbuilder builder=new saxbuilder(false); try { document document=builder.build(filename); element employees=document.getrootelement(); list employeelist=employees.getchildren(employee); for(int i=0;i
dom4j 是一种解析 xml 文档的开放源代码 xml 框架。本文介绍如何使用包含在 dom4j 中的解析器创建并修改 xml 文档。
dom4j api 包含一个解析 xml 文档的工具。本文中将使用这个解析器创建一个示例 xml 文档。
清单 1. 示例 xml 文档(catalog.xml)
<?xml version="1.0" encoding="utf-8"?> <catalog> <!--an xml catalog--> <?target instruction?><journal title="xml zone" publisher="ibm developerworks"> <article level="intermediate" date="december-2001"> <title>java configuration with xml schema</title> <author> <firstname>marcello</firstname> <lastname>vitaletti</lastname> </author> </article></journal> </catalog>
然后使用同一个解析器修改 catalog.xml,清单 2 是修改后的 xml 文档,catalog-modified.xml。
清单 2. 修改后的 xml 文档(catalog-modified.xml)
<?xml version="1.0" encoding="utf-8"?><catalog> <!--an xml catalog--><?target instruction?><journal title="xml zone" publisher="ibm developerworks"><article level="introductory" date="october-2002"> <title>create flexible and extensible xml schemas</title> <author><firstname>ayesha</firstname> <lastname>malik</lastname> </author> </article></journal></catalog>
与 w3c dom api 相比,使用 dom4j 所包含的解析器的好处是 dom4j 拥有本地的 xpath 支持。dom 解析器不支持使用 xpath 选择节点。
本文包括以下几个部分:
预先设置
创建文档
修改文档
预先设置
这个解析器可以从 获取。通过设置使 dom4j-1.4/dom4j-full.jar 能够在 classpath 中访问,该文件中包括 dom4j 类、xpath 引擎以及 sax 和 dom 接口。如果已经使用了 jaxp 解析器中包含的 sax 和 dom 接口,向 classpath 中增加 dom4j-1.4/dom4j.jar 。 dom4j.jar包括 dom4j 类和 xpath 引擎,但是不含 sax 与 dom 接口。
创建文档
本节讨论使用 dom4j api 创建 xml 文档的过程,并创建示例 xml 文档 catalog.xml。
使用 import 语句导入 dom4j api 类:
import org.dom4j.document;
import org.dom4j.documenthelper;
import org.dom4j.element;
使用 documenthelper 类创建一个文档实例。 documenthelper 是生成 xml 文档节点的 dom4j api 工厂类。
document document = documenthelper.createdocument();
使用 addelement() 方法创建根元素 catalog 。 addelement() 用于向 xml 文档中增加元素。
element catalogelement = document.addelement(catalog);
在 catalog 元素中使用 addcomment() 方法添加注释“an xml catalog”。
catalogelement.addcomment(an xml catalog);
在 catalog 元素中使用 addprocessinginstruction() 方法增加一个处理指令。
catalogelement.addprocessinginstruction(target,text);
在 catalog 元素中使用 addelement() 方法增加 journal 元素。
element journalelement = catalogelement.addelement(journal);
使用 addattribute() 方法向 journal 元素添加 title 和 publisher 属性。
journalelement.addattribute(title, xml zone);
journalelement.addattribute(publisher, ibm developerworks);
向 article 元素中添加 journal 元素。
element articleelement=journalelement.addelement(article);
为 article 元素增加 level 和 date 属性。
articleelement.addattribute(level, intermediate);
articleelement.addattribute(date, december-2001);
向 article 元素中增加 title 元素。
element titleelement=articleelement.addelement(title);
使用 settext() 方法设置 article 元素的文本。
titleelement.settext(java configuration with xml schema);
在 article 元素中增加 author 元素。
element authorelement=articleelement.addelement(author);
在 author 元素中增加 firstname 元素并设置该元素的文本。
element firstnameelement=authorelement.addelement(firstname);
firstnameelement.settext(marcello);
在 author 元素中增加 lastname 元素并设置该元素的文本。
element lastnameelement=authorelement.addelement(lastname);
lastnameelement.settext(vitaletti);
可以使用 adddoctype()方法添加文档类型说明。
document.adddoctype(catalog, null,file://c:/dtds/catalog.dtd);
这样就向 xml 文档中增加文档类型说明:
<!doctype catalog system "file://c:/dtds/catalog.dtd">
如果文档要使用文档类型定义(dtd)文档验证则必须有 doctype。
xml 声明 <?xml version="1.0" encoding="utf-8"?> 自动添加到 xml 文档中。
清单 3 所示的例子程序 xmldom4j.java 用于创建 xml 文档 catalog.xml。
清单 3. 生成 xml 文档 catalog.xml 的程序(xmldom4j.java)
import org.dom4j.document;import org.dom4j.documenthelper;import org.dom4j.element;import org.dom4j.io.xmlwriter;import java.io.*;public class xmldom4j{public void generatedocument(){ document document = documenthelper.createdocument(); element catalogelement = document.addelement(catalog); catalogelement.addcomment(an xml catalog); catalogelement.addprocessinginstruction(target,text); element journalelement = catalogelement.addelement(journal); journalelement.addattribute(title, xml zone); journalelement.addattribute(publisher, ibm developerworks); element articleelement=journalelement.addelement(article); articleelement.addattribute(level, intermediate); articleelement.addattribute(date, december-2001); element titleelement=articleelement.addelement(title); titleelement.settext(java configuration with xml schema); element authorelement=articleelement.addelement(author); element firstnameelement=authorelement.addelement(firstname); firstnameelement.settext(marcello); element lastnameelement=authorelement.addelement(lastname); lastnameelement.settext(vitaletti); document.adddoctype(catalog,null,file://c:/dtds/catalog.dtd);try{ xmlwriter output = new xmlwriter( new filewriter(new file(c:/catalog/catalog.xml))); output.write( document ); output.close(); } catch(ioexception e){ system.out.println(e.getmessage()); } }public static void main(string[] argv){ xmldom4j dom4j=new xmldom4j(); dom4j.generatedocument(); } }
这一节讨论了创建 xml 文档的过程,下一节将介绍使用 dom4j api 修改这里创建的 xml 文档。
修改文档
这一节说明如何使用 dom4j api 修改示例 xml 文档 catalog.xml。
使用 saxreader 解析 xml 文档 catalog.xml:
saxreader saxreader = new saxreader(); document document = saxreader.read(inputxml);
saxreader 包含在 org.dom4j.io 包中。
inputxml 是从 c:/catalog/catalog.xml 创建的 java.io.file。使用 xpath 表达式从 article 元素中获得 level 节点列表。如果 level 属性值是“intermediate”则改为“introductory”。
list list = document.selectnodes(//article/@level ); iterator iter=list.iterator(); while(iter.hasnext()){ attribute attribute=(attribute)iter.next(); if(attribute.getvalue().equals(intermediate)) attribute.setvalue(introductory); }
获取 article 元素列表,从 article 元素中的 title 元素得到一个迭代器,并修改 title 元素的文本。
list = document.selectnodes(//article ); iter=list.iterator(); while(iter.hasnext()){ element element=(element)iter.next(); iterator iterator=element.elementiterator(title); while(iterator.hasnext()){ element titleelement=(element)iterator.next(); if(titleelement.gettext().equals(java configuration with xml schema)) titleelement.settext(create flexible and extensible xml schema); } }
通过和 title 元素类似的过程修改 author 元素。
清单 4 所示的示例程序 dom4jparser.java 用于把 catalog.xml 文档修改成 catalog-modified.xml 文档。
清单 4. 用于修改 catalog.xml 的程序(dom4jparser.java)
import org.dom4j.document;import org.dom4j.element;import org.dom4j.attribute;import java.util.list;import java.util.iterator;import org.dom4j.io.xmlwriter;import java.io.*;import org.dom4j.documentexception;import org.dom4j.io.saxreader;public class dom4jparser{public void modifydocument(file inputxml){try{ saxreader saxreader = new saxreader(); document document = saxreader.read(inputxml); list list = document.selectnodes(//article/@level ); iterator iter=list.iterator();while(iter.hasnext()){ attribute attribute=(attribute)iter.next();if(attribute.getvalue().equals(intermediate)) attribute.setvalue(introductory); } list = document.selectnodes(//article/@date ); iter=list.iterator();while(iter.hasnext()){ attribute attribute=(attribute)iter.next();if(attribute.getvalue().equals(december-2001)) attribute.setvalue(october-2002); } list = document.selectnodes(//article ); iter=list.iterator();while(iter.hasnext()){ element element=(element)iter.next(); iterator iterator=element.elementiterator(title);while(iterator.hasnext()){ element titleelement=(element)iterator.next();if(titleelement.gettext().equals(java configuration with xmlschema)) titleelement.settext(create flexible and extensible xml schema); } } list = document.selectnodes(//article/author ); iter=list.iterator();while(iter.hasnext()){ element element=(element)iter.next(); iterator iterator=element.elementiterator(firstname);while(iterator.hasnext()){ element firstnameelement=(element)iterator.next();if(firstnameelement.gettext().equals(marcello)) firstnameelement.settext(ayesha); } } list = document.selectnodes(//article/author ); iter=list.iterator();while(iter.hasnext()){ element element=(element)iter.next(); iterator iterator=element.elementiterator(lastname);while(iterator.hasnext()){ element lastnameelement=(element)iterator.next();if(lastnameelement.gettext().equals(vitaletti)) lastnameelement.settext(malik); } } xmlwriter output = new xmlwriter(new filewriter( new file(c:/catalog/catalog-modified.xml) )); output.write( document ); output.close(); } catch(documentexception e) { system.out.println(e.getmessage()); } catch(ioexception e){ system.out.println(e.getmessage()); } }public static void main(string[] argv){ dom4jparser dom4jparser=new dom4jparser(); dom4jparser.modifydocument(new file(c:/catalog/catalog.xml)); } }
结束语:包含在 dom4j 中的解析器是一种用于解析 xml 文档的非验证性工具,可以与jaxp、crimson 或 xerces 集成。本文说明了如何使用该解析器创建和修改 xml 文档。
以上就是解析xml的四种方法的详细内容。
