目前xml解析的方法主要用两种:
1、dom解析:(document object model,即文档对象模型)是w3c组织推荐的解析xml的一种方式。
使用dom解析xml文档,该解析器会先把xml文档加载到内存中,生成该xml文档对应的document对象,然后把xml文档中的各个标签元素变成相应的element对象,文本会变成text对象,属性会变成attribute对象,并按这些标签、文本、属性在xml文档中的关系保存这些对象的关系。
缺点:消耗内存,所以使用dom解析xml文档时不能解析太大的xml文档,否则有可能会造成内存溢出。
优点:使用dom解析xml文档可以很方便的执行增删改查操作(可以直接根据节点对应的对象进行操作)。
2、sax解析:simple api for xml,不是官方标准,但它是xml社区事实上的标准,几乎所有的xml解析器都支持它。
使用sax解析xml文档,该解析器会从上往下读,读一行,解析一行;
优点:因为它解析xml文档是采取读一行,解析一行的方式,所以它不会对内存造成压力。
缺点:不适合执行增删改查的操作(也是因为它解析xml文档时采取的读一行解析一行的方式,所以它不能往回操作),只适合对xml文档进行读取操作。
======================================================================================================
补充:
xml解析开发包:jaxp(sun)、jdom、dom4j;
======================================================================================================
调整jvm内存大小:
当我们要解析的xml文档内存比较大、而且要对该xml中的节点数据进行相关的操作时,使用这两种解析方式显然都会不方便,这时就需要调整jvm内存的大小了。
jvm默认的允许最大内存容量是64m(根据jdk的版本不同,默认的最大容量值不一样,jdk5.0版本的是64mb,jdk7版本的是170mb)。
调整jvm内存大小的方法(相应的命令为:-xmx内存大小值单位):
在eclipse中的项目导航框中右击相应的java程序》》run as》》open run dialog...》》打开run对话框》》选择arguments选项,在开窗口中有两个输入框,第一个是程序的参数输入框,第二个是vm的参数输入框,在第二个vm的参数输入框中输入xmx200m》》点击右下角的run按钮,执行相应的java程序,就不会报outofmemoryerror的错误了。
======================================================================================================
xml解析开发包:
1、jaxp:jaxp开发包是j2se的一部分,它由javax.xml、org.w3c.dom、org.xml.sax包及其子包组成。
在javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工厂类,可以得到xml文档的dom或sax的解析器,从而实现对xml文档的解析。
首先、创建工厂:
documentbuilderfactory factory = documentbuilderfactroy.newinstance();//因为documentbuilderfactory类是抽象类,不能new出它的对象只能调用它的静态方法获取它的对象。
其次、得到dom解析器:
documentbuilder builder = factory.newdocumentbuilder();
然后、加载xml文档,得到代表文档的document对象:
document document = builder.parse(*.xml);
拿到代表xml文档的document对象就可以操作xml文档中的各个节点了。
======================================================================================================
补充:
dom解析下,xml文档的每一个组成部分都会用一个对象表示,例如标签用element,属性用attribute,但不管什么对象,都是node的子类,所以在开发中可以把获取到的任意节点都当作node对待。
xml编程(crud)
create、read、update、delete
添加、查询、更新、删除;
除了这两种解析方法外,还有另外的解析方法。。。
======================================================================================================
在对xml文档进行添加、修改和删除操作时,不仅要更新document对象还要更新xml文档(把更新后的document对象重写到xml文档中)。
javax.xml.transform包中的transformer类用于把代表xml文档的document对象转换为某种格式后输出,例如把xml文档应用样式表后转换成一个html文档。利用这个对象,当然也可以把document对象又重新写入到一个xml文档中。源和目的地。可以通过:
javax.xml.transform.dom.domsource类来关联要转换的document对象,
用javax.xml.transform.stream.streamresult对象来表示数据的目的地。
transformer对象通过transformerfactory获得。
transformer类通过transform方法完成转换操作,该方法接收个
(工厂对象(transformerfactory)》》》转换器对象(transformer)》》》转换方法(transform(domsource 源,streamresult 目的地);))
======================================================================================================
sax解析:
sax解析采用事件处理的方式解析xml文件,利用sax解析xml文档,涉及两个部分:解析器和事件处理器:
解析器可以使用jaxp的api创建,创建出sax解析器后,就可以指定解析器去去解析某个xml文档。
解析器采用sax方式在解析某个xml文档时,它只要解析到xml文档的一个指定部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松的得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
1、创建解析工厂;
saxparserfactory fac = saxparserfactory.newinstance();
2、获取解析器;
saxparser sp = fac.newsaxparser();
3、得到读取器;
xmlreader re = sp.getxmlreader();
4、设置内容处理器;
re.setcontenthandler(new contenthandler(){ /*实现接口的代码块*/});
(或者:re.setcontenthandler(new defaulthandler());/*参数为defaulthandler类的子类*/)
第一种方法是解析整个xml文档,第二种方法可以只解析某个标签;
其实还有一种内容处理器,也是先继承defaulthandler类,然后把解析的内容封装到bean对象中。
5、读取xml文档内容;
re.parse(*.xml);
======================================================================================================
xml解析开发包:
2、dom4j:
saxreader saxreader = new saxreader();
document doc = saxreader.read(new file());
outputformat format = outputformat.createprettyprint();//该对象标明格式按漂亮的格式进行输出;另外还有一个对象是按紧凑的格式进行输出;
format.setencoding(utf-8);
xmlwriter xmlwriter = new xmlwriter(new fileoutputstream(),format);
xmlwriter.write(doc);//如果xmlwriter对象采用的流是字节流,那么该对象会先把doc对象按format对象给定的编码格式转换成字节,然后把数据交给字节流进行操作。
writer.close();//最后要关闭资源
======================================================================================================
xpath:
使用xpath可以快速定位到某个节点;
list list = document.selectnodes(//foo/bar);//获取foo节点下的所有bar节点;
node node = document.selectsinglenode(//foo/bar);//获取foo节点下的第一个bar节点;
单斜杠是绝对路径即从根节点开始;
双斜杠是相对路径即从所有当前节点开始;
星号“*”表示选择所有由星号之前的路径所定位的元素;
例如:
/aa/bb/*表示选择所有路径依附于/aa/bb的元素;
/*/*/*/bbb表示选择所有的有3个祖先元素的bbb元素;
//bb[@*]表示选择有任意属性的bb元素;
//bb[not(@*)]表示选择没有属性的bb元素;
//bb[@id='b1']表示选择含有属性id='b1'的bb元素;
