简单的Java读取xml文件

 

 

 最近有一个任务是将项目中的一些资源代码转化成是可配置的,因此,心里想到了使用XML文件来配置,虽然最后使用了properties来配置,但是突然想自己读取一把xml文件,并且不借助jdom之类的jar包来解析

 

想到xml配置文件是一个循环结构,因此最开始想使用递归方法,但是到后来觉得递归找子项不太好找(不想记录尖括号位置那种写法),后来觉得用数据结构里面建立树的写法来建立"xml 树",我觉得这种思路是对的,因为即使是html标准的文档也会使用domtree的概念,而且一些解析xml的jar 包最后得到的也是近似是树的结构。

 

我只是做了一个很小的测试,今天北京雾霾特别大,头昏脑涨的,也就没有考虑过多复杂的情形,以下面的xml为例做测试

 

 

<school>
 <colleage>
	<student>
			<name>luchi</name>
			<sex>male</sex>
	</student>
	<student>
			<name>lushuiye</name>
			<sex>female</sex>
	</student>
	<student>
		<name>zhangsan</name>
		<sex>male</sex>
	</student>
 </colleage>
 
<gate>
	<color>red</color>
	<text>welcome to graduate school</text>
</gate>
 
</school>

 

我把每个尖括号都看作是一个类(等同于C语言的结构体),有其属性,特别是有parent和child这两个属性,类如下:

package test;

import java.util.HashSet;
import java.util.Set;

public class Node {
	
	private String name;
	private String value;
	private Set<Node> child=new HashSet<Node>();
	private Node parent=null;
	public Node getParent() {
		return parent;
	}
	public void setParent(Node parent) {
		this.parent = parent;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}
	public Set<Node> getChild() {
		return child;
	}
	public void setChild(Set<Node> child) {
		this.child = child;
	}
	
	
	
	 

}

 把类的对象看作是树的节点,有子女和孩子,我的处理逻辑是读取标签,如果遇到<>标签就简历一个新的树节点,如果遇到文本则更新当前节点的属性值,如果遇到结束标签,则将当前节点设置成当前节点的父节点(退一个节点),然后继续扫面文档,直到文档结束

具体代码如下

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

public class ReadXML {
	
	
	String path="C:\\Users\\dell\\Desktop\\test.xml";
	String text="";
	//根节点
	Node root=new Node();
	//设置当前节点为空,当前节点就是这棵树最新构造的节点
	Node currentNode=null;
	
	//读取内容并解析
	public void parse() throws IOException{
		
		File xmlFile=new File(path);
		InputStream in=new FileInputStream(xmlFile);
		int len;
		byte []buff=new byte[1024];
		while((len=in.read(buff))>0){
			
			text+=new String(buff);
		}
		root.setParent(null);
		parseText(root,text);
	}


	
	/*解析的主要方法
	 * 
	 * @param root 传入的根节点
	 * @param text 传入的文本
	 * @author luchi
	*/
	private void parseText(Node root,String text) {
		
		currentNode=root;
		
		//看是不是第一次构造根节点
		boolean isFirst=true;
		while(!text.trim().equals("")){
			
			//处理开始标签
			if(text.startsWith("<")&& !text.startsWith("</")){
				
				int head_begin=text.indexOf("<");
				int head_end=text.indexOf(">");
				String name=text.substring(head_begin+1,head_end);
				if(currentNode.getParent()==null && isFirst){
					
					currentNode.setName(name);
					isFirst=false;
					
				}else{
					Node child=new Node();
					child.setName(name);
					child.setParent(currentNode);
					currentNode.getChild().add(child);
					currentNode=child;
//					System.out.println("     "+currentNode.getName());
					
					
				}
				text=text.substring(head_end+1).trim();
				continue;
				
			}else if(!text.startsWith("</") && !text.startsWith("<")){  //处理正文属性标签
				
				int head_begin=text.indexOf("</");
				String value=text.substring(0,head_begin).trim();
				currentNode.setValue(value);
				text=text.substring(head_begin).trim();
				continue;
				
			}else if(text.startsWith("</")){  //处理结尾标签,回溯节点
				
				Node temp=currentNode.getParent();
				if(temp!=null){
					
					currentNode=temp;
				}
				int end_end=text.indexOf(">");
				text=text.substring(end_end+1).trim();
				continue;
			}
			
		}
		
	}
	public void printGivenNumBlank(int blank){
		for(int i=0;i<blank;i++){
			System.out.print(" ");
		}
	}
	
	//深度遍历结果
	public void show(Node srcNode,int blank){
		if(srcNode!=null){
			printGivenNumBlank(blank);
			System.out.print(srcNode.getName());
			if(srcNode.getValue()!=null && !srcNode.getValue().equals("")){
				System.out.print("   "+srcNode.getValue());
			}
			System.out.println();
			for(Node child:srcNode.getChild()){
				show(child,blank*2);
			}
			
		}
	}
	
	public void result(){
		show(root,5);
	}
	

}

 代码注释差不多写清楚了,最后我们来看一下测试程序

@Test
	public void testXML() throws IOException {
		
		ReadXML parser=new ReadXML();
		parser.parse();
		parser.result();
		
	}

 以及该结果

     school
          gate
                    text   welcome to graduate school
                    color   red
          colleage
                    student
                                        sex   male
                                        name   zhangsan
                    student
                                        name   luchi
                                        sex   male
                    student
                                        sex   female
                                        name   lushuiye

 如图所示打印出了一个横过来的xml树,说明处理成功,今天人比较疲倦,逻辑比较简单,也没有涉及到复杂的xml格式等情况,就到这里,over!

猜你喜欢

转载自luchi007.iteye.com/blog/2247458
今日推荐