java自定义解析XML文件解析

本文介绍了一种自定义XML解析器的设计与实现方法,通过组合模式构建XML文档的树形结构,支持按路径获取节点值及属性等功能,适用于定制化需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义解析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;//叶子节点标识

  

   //节点的属性(每个节点的基本成员变量namevalue,属性集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"));

   }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值