java-XML

XML不再多说,XML 约束也不用说了,这里讲讲java如何对XML操作。

java中使用XML,目前常用的就是Jaxp(sun)和dom4j了,这里先讲讲java自带的Jaxp包

JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成

Jaxp的xml解析器有两种,一种是DOM解析器,一种是SAX解析器,两种各自应用在不同的场景上。

在DOM解析时,会把xml中各个节点视为对象,然后根据父子关系相互嵌套。优点时容易操纵,缺点也很明显,必须全部通读xml并加载进内存。

DOM解析的流程:

1,DocumentBuilderFactory是抽象类,newInstance()方法会根据本地平台安装的xml解析器自动创建相应的工厂实力

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

2,DocumentBuilder的newDocumentBuilder()方法会得到本地xml解析器相应的DocumentBuilder实力

DocumentBuilder documentB = dbf.newDocumentBuilder();

3,解析xml,根据DocumentBuilder的parse方法。

Document document = documentB.parse(new File(path));
//看文档可以知道,parse可以从解析File、InputSource(经过包装的InputStream)、InputStream和URI字符串

4,Document代表了整个XML文档,首先获取根节点,Element就是标签,它们都属于Node,也就是说,都实现了Node接口

Element root=document.getDocumentElement();

5,下面就是增删改查了

增加结点

//增加一个结点,注意,增加节点是对document操作,Document实现了这个方法
Element newStudent=document.createElement("student");
			
//增加一个属性,属性也算是结点,一切都是Node
Attr cid=document.createAttribute("idcard");
//给属性设置值
cid.setValue("1121");
			
//将属性添加进这个标签
newStudent.setAttributeNode(cid);
			
//最后,将这个结点添加进根节点,注意,是对根节点添加,不是Document
root.appendChild(newStudent);

提取某节点信息(查)

//首先根据第3步,已经获得根结点,也就是Element root


//获取所有标签名为sutdent的节点集合
NodeList students=root.getElementsByTagName("student");

//至于获取标签属性以及text内容,自行看手册

//要注意的是,换行和制表符'\n\t'这些,也会被当做text内容解析
//至于xml的编码问题,都是自动的,不用手动设置了。

更改结点内容(很多都是Node接口的方法,自行查看手册即可)

//设置标签内容
Node.setTextContent(String text)

//设置属性内容
Attr.setValue(String value)

删除结点

Node.removeChild(Node node)

6,操作完xml,保存结果

javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。
利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
//1、获得Transformer工厂
TransformerFactory tff=TransformerFactory.newInstance();

//2、对于DOM对象,使用树来表示,肯定是个多叉树了,,,
//这个类,就是将树,变为结果树
Transformer tf = tff.newTransformer();

//3、把document(DOM)转换为xml source
Source sc=new DOMSource(document);

//4、创建一个DOM目标,这里是个流
Result rs=new StreamResult(new File(path_URI));

//5、将 XML Source 转换为 Result,这样就写入数据流了
tf.transform(sc, rs);

DOM解析就到这里,如果以网络流读取一个大的xml文件的话,这样肯定是不行的,不可能一直等到它全部读完载入内存再操作吧。。。。。光读取的话,就用SAX了。

SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
•解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
•解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。

事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理

我们常用的就是ContentHandler了。

下面是sax示例

//定义工厂api,用以配置和获取sax解析器
		SAXParserFactory spf = SAXParserFactory.newInstance();
		
		//得到解析器对象
		SAXParser sp = spf.newSAXParser();
		
		//得到一个xmlreader读取器
		XMLReader xmlReader = sp.getXMLReader();

		//注册一个内容事件处理器 ContentHandler,一般情况下,使用ContentHandler接口的已知
		//子类DefaultHandler就行了
		
		xmlReader.setContentHandler(new DefaultHandler(){
			//为了方便,以内部类重写需要使用到的方法
			
			//开始读取标签
			public void startElement(String uri, //命名空间
                    String localName, //标签名
                    String qName, //限定名称
                    Attributes attributes //属性
                    ){
				
				///////////////////////////
				//获取标签的个数
				attr.getLength();
				//其它的看手册				
			}
			
			//开始读取文档
			public void startDocument(){
				
			}
			
			//读取到标签尾
			public void endElement( String namespaceURI,
		              String localName,
		              String qName ) {

		   }
			
			//读取标签体,注意的是,sax是分段读取的,每次最大读取是2kb
			public void characters(char[] ch,
                    int start,
                    int length
                   ){
				//读取大数据的时候注意sax是分段读取的,每次最大读取是2kb
				
				
			}
           

			
		});
		
		
		//开始读取xml数据
		xmlReader.parse("book.xml");

到这里,我们发现SAX虽然比DOM效率高,但是它是顺序读取的,无法回头,且只能从头到尾。

现在就可以使用Dom4j了,它是第三方包

Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
使用Dom4j开发,需下载dom4j相应的jar文件。

lDOM4j中,获得Document对象的方式有三种:
//1.读取XML文件,获得document对象            
          SAXReader reader = new SAXReader();
          Document   document = reader.read(new File("input.xml"));

//2.解析XML形式的文本,得到document对象.
          String text = "<members></members>";  
          Document document = DocumentHelper.parseText(text);
//3.主动创建document对象.
          Document document = DocumentHelper.createDocument();             //创建根节点
          Element root = document.addElement("members");

dom4j 中结点对象的操作:

  //1.获取文档的根节点.
	Element root = document.getRootElement();
	
  //2.取得某个节点的子节点.
	Element element=node.element(“书名");
	
  //3.取得节点的文字
	String text=node.getText();
  //4.取得某节点下所有名为“member”的子节点,并进行遍历.
	List nodes = rootElm.elements("member");
	for (Iterator it = nodes.iterator(); it.hasNext();) {
		Element elm = (Element) it.next();
		// do something
	}
	
  //5.对某节点下的所有子节点进行遍历.
	for(Iterator it=root.elementIterator();it.hasNext();){
		Element element = (Element) it.next();
 		// do something
	}
	
  //6.在某节点下添加子节点.
	Element ageElm = newMemberElm.addElement("age");
	
  //7.设置节点文字.
	element.setText("29");
	
  //8.删除某节点.
	//childElm是待删除的节点,parentElm是其父节点
	parentElm.remove(childElm);
  //9.添加一个CDATA节点.
	Element contentElm = infoElm.addElement("content");
	contentElm.addCDATA(diary.getContent());

对节点对象属性的操作:

  //1.取得某节点下的某属性
	Element root=document.getRootElement();
	//属性名name
    Attribute attribute=root.attribute("size");

  //2.取得属性的文字
 	String text=attribute.getText();

  //3.删除某属性
	Attribute attribute=root.attribute("size");
	root.remove(attribute);
	
  //4.遍历某节点的所有属性
	Element root=document.getRootElement(); 
	for(Iterator it=root.attributeIterator();it.hasNext();){
		Attribute attribute = (Attribute) it.next();
		String text=attribute.getText();
		System.out.println(text);
	}
  //5.设置某节点的属性和文字.
	newMemberElm.addAttribute("name", "sitinspring");

  //6.设置属性的文字
	Attribute attribute=root.attribute("name");
	attribute.setText("sitinspring");

在指定位置中插入元素:

1.得到插入位置的节点列表(list)
2.调用list.add(index,elemnent),由index决定element的插入位置。
3.list中存储的是引用,对list进行了更改,既对document进行了更改
//Element元素可以通过DocumentHelper对象得到。示例代码:

Element aaa = DocumentHelper.createElement("aaa");
aaa.setText("aaa");

List list = root.element("书").elements();
list.add(1, aaa);

写入XML文档

  //1.文档中全为英文,不设置编码,直接写入的形式.
	XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));
	writer.write(document);
	writer.close();

  //2.文档中含有中文,设置编码格式写入的形式.OutputFormat format = OutputFormat.createPrettyPrint();// 指定XML编码                   
	format.setEncoding("GBK");
	XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
	writer.write(document);
	writer.close();

XML与字符串的转换

  //1.将字符串转化为XML 
	String text = "<members> <member>sitinspring</member></members>";
	Document document = DocumentHelper.parseText(text);

  //2.将文档或节点的XML转化为字符串.
	SAXReader reader = new SAXReader();
	Document   document = reader.read(new File("input.xml"));
	Element root=document.getRootElement();    
	String docXmlText=document.asXML();
	String rootXmlText=root.asXML();
	Element memberElm=root.element("member");
	String memberXmlText=memberElm.asXML();

在Dom4j中使用xpath查询路径

xpath路径表达式就像正则表达式一样,可以免去自己写遍历对比代码了。

//dom4j的包中的document..........
List<Node> list = document.selectNodes("//xpath");

上面的所有代码基本上算是模板代码了,用的时候多看手册,拷贝粘贴就ok了

posted on 2011-06-01 20:23  黑暗伯爵  阅读(868)  评论(0编辑  收藏  举报

导航