自定义解析XML文件解析:
例:test.xml文件
<struts>
<package name="default" namespace="/"extends="struts-default">
<actionname="role_*" class="roleAction" method="{1}">
<resultname="privilegeUI">/jsp/roleAction/setPrivilege.jsp</result>
<resultname="list">/jsp/roleAction/list.jsp</result>
<resultname="saveUI">/jsp/roleAction/saveUI.jsp</result>
</action>
<a>value</a>
</package>
</struts>
1. 要求:
1) 根据xml文件的路径获得值value:(struts/package/a) 值为:value;
2) 根据xml文件的路径+name值来获得value:
(struts/package/action/result+list);
3) 根据xml文件的路径获得+属性来获得属性值:
(struts/package/+extends)或者(struts/package/+namespace)
…………….
实现:以下实现类都经过测试
树形结构:中间节点和叶子节点
本例应用到了程序设计模式中的组合模式
重点理解:树的创建:
利用stack的特性,将test.xml中的各节点以树的形式存储在Arraylist集合
存储形式:
===============================================================================
import java.util.Map;
/**
* 叶节点和中间节点的通用抽象类
* 抽象即为共享,接口即为顺序
* @author wl
*
*/
public abstractclassNode {
//判断各个状态的标识
public static final int NODE_START=0;//中间节点开始标识
public static final int NODE_END=1;//中间节点终止标识
public static final int NODE_LEAF=2;//叶子节点标识
//节点的属性(每个节点的基本成员变量name,value,属性集pro)
protected String name; //节点的名字
protectedMap<String,String> pro;//属性集
protected String value; //
//判断节点的类型,返回标识
//开始<....>
//终止</...>
//叶子节点<...>...</...>
public static int getType(String s){
int num=0;
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='<'){
num++;
}
}
if(num==1){ //只有一个<
if(s.charAt(1)=='/'){
return NODE_END;
}
return NODE_START;
}
return NODE_LEAF;
}
//树形结构中添加子节点集
public void addNode(Node node){}
public abstract void display();
}
==========================================================================
import java.util.HashMap;
/**
* 叶子节点
* @author wl
*
*/
public classLeafNode extendsNode {
public LeafNode(String s){
int start=1;
int end=s.indexOf(">");
//如得到结果:result name="privilegeUI"
String leaf=s.substring(start, end);
String[] leaf2=leaf.split(" ");
//1获得name
name=leaf2[0];
//2判断是否有属性集,获得属性集pro
if(leaf2.length>=2){
pro=new HashMap();
for(int i=1;i<leaf2.length;i++){
String[] leaf3=leaf2[i].split("=");
pro.put(leaf3[0], leaf3[1].substring(1, leaf3[1].length()-1));
}
}
//3获得value
start=end+1;
end=s.indexOf("<", start);
value=s.substring(start, end);
}
public void display() {
System.out.println(name);
}
}
============================================================================
importjava.util.ArrayList;
importjava.util.HashMap;
/**
* 中间节点
* @author wl
*
*/
public classMidNode extends Node {
//存储中间节点的子集节点
ArrayList<Node> nodeList=newArrayList();
//初始化节点的值,如:action name="role_*" class="roleAction"method="{1}"
public MidNode(String s){
String mid=s.substring(1,s.length()-1);
String[] mid2=mid.split("");
//1获得name值
name=mid2[0];
//2获得属性集合pro
if(mid2.length>=2){
pro=new HashMap();
for(inti=1;i<mid2.length;i++){
String[]mid3=mid2[i].split("=");
pro.put(mid3[0],mid3[1].substring(1, mid3[1].length()-1));
}
}
}
//添加子节点
public void addNode(Node node){
nodeList.add(node);
}
public void display() {
System.out.println(name);
for(inti=0;i<nodeList.size();i++){
nodeList.get(i).display();
}
}
}
===============================================================================
importjava.io.BufferedReader;
importjava.io.FileReader;
importjava.util.ArrayList;
importjava.util.Map;
importjava.util.Stack;
/**
* xml文件解析类
* 路径path格式../../../..
* @author wl
*
*/
public classXMLmessage {
Node root;
//根据xml文件创建树
public boolean createTree(String strFile)throws Exception{
//文件输入
FileReader in=newFileReader(strFile);
BufferedReader br=newBufferedReader(in);
String s=br.readLine();
s=s.trim();
root=new MidNode(s);
//定义栈,用栈控制创建树
Stack<Node> sk=new Stack();
sk.push(root); //压入栈顶
while((s=br.readLine())!=null){
s=s.trim();
if(s.equals("")){
continue;
}
//获得节点的type
int logo=Node.getType(s);
if(logo==Node.NODE_START){
Node node=newMidNode(s);
Node top=sk.peek();
top.addNode(node);
sk.push(node);
}elseif(logo==Node.NODE_END){
sk.pop();
}else{
//叶子节点
Node node=newLeafNode(s);
Node top=sk.peek();
top.addNode(node);
}
}
//关闭资源
in.close();
br.close();
return true;
}
//通用的遍历方法(从给定路径的倒数第二个节点以前)
private Node getResult(String[] s){
Node result=root;
if(!root.name.equals(s[0])){
return null;
}
ArrayList<Node>mid=((MidNode)root).nodeList;
int j;
for(int i=1;i<s.length-1;i++){
Boolean mark=false;
for(j=0;j<mid.size();j++){
Stringname=mid.get(j).name;
if(name.equals(s[i])){
mark=true;
break;
}
}
if(!mark){
return null;
}
result=mid.get(j);
mid=((MidNode)result).nodeList;
}
return result;
}
//1由路径遍历得到value
public String getValue(String path){
String[]s=path.split("/");
Node result=getResult(s);
if(result==null){
return null;
}
ArrayList<Node>mid=((MidNode)result).nodeList;
Boolean mark=false;
for(int i=1;i<mid.size();i++){
result=mid.get(i);
if(result.name.equals(s[s.length-1])){
mark=true;
break;
}
}
if(mark){
return result.value;
}else{
return null;
}
}
//2由路径和name遍历得到value
public String getValue(String path,Stringname){
String[]s=path.split("/");
Node result=getResult(s);
if(result==null){
return null;
}
ArrayList<Node>mid=((MidNode)result).nodeList;
Boolean mark=false;
for(int i=0;i<mid.size();i++){
result=mid.get(i);
Map<String,String>map=result.pro;
if(result.name.equals(s[s.length-1])&&name.equals(map.get("name"))){
mark=true;
break;
}
}
if(mark){
return result.value;
}else{
return null;
}
}
//3由路径和属性得到属性值
public String getProperty(Stringpath,String pro){
String[]s=path.split("/");
Node result=getResult(s);
if(result==null){
return null;
}
ArrayList<Node>mid=((MidNode)result).nodeList;
Boolean mark=false;
for(int i=0;i<mid.size();i++){
result=mid.get(i);
if(result.name.equals(s[s.length-1])){
mark=true;
break;
}
}
if(mark){
Map<String,String>map=result.pro;
return map.get(pro);
}else{
return null;
}
}
}
===================================================================================
/**
* xml文件解析测试类
* @author wl
*
*/
public classTest {
public static void main(String args[]) throws Exception{
XMLmessagexml=new XMLmessage();
xml.createTree("D:/test.xml");
System.out.println(xml.getValue("struts/package/a"));
System.out.println(xml.getValue("struts/package/action/result", "privilegeUI"));
System.out.println(xml.getProperty("struts/package/action","class"));
}
}