欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

dom4j从jar包中读取xml文件的方法

程序员文章站 2024-02-23 22:26:10
进行封装的时候,我们常常需要用xml来定义一些规范,在单独运行读取的时候当然不会有问题,但这些xml是往往是放在jar包里的,这样一来,这些东西就找不出来了。文中用到的xm...

进行封装的时候,我们常常需要用xml来定义一些规范,在单独运行读取的时候当然不会有问题,但这些xml是往往是放在jar包里的,这样一来,这些东西就找不出来了。文中用到的xml定义如下:

复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<accesos>
 <item>
  <socio name="adsf">
   <numero>00045050</numero>
   <reposicion>0</reposicion>
   <nombre>moises moreno</nombre>
   <turnos>
    <lu>t1</lu>
    <ma>t2</ma>
    <mi>t3</mi>
    <ju>t4</ju>
    <vi>t5</vi>
    <sa>t6</sa>
    <do>t7</do>
   </turnos>
  </socio>
 </item>
 <item>
  <socio name="adsfa">
   <numero>00045051</numero>
   <reposicion>0</reposicion>
   <nombre>ruth pena</nombre>
   <turnos>
    <lu>s1</lu>
    <ma>s2</ma>
    <mi>s3</mi>
    <ju>s4</ju>
    <vi>s5</vi>
    <sa>s6</sa>
    <do>s7</do>
   </turnos>
  </socio>
 </item>
</accesos>

下面来看代码:

复制代码 代码如下:

public void read(){ 
    try { 
        document doc = new saxreader().read(new file("src/user.xml")); 
        list<element> itemlist =  doc.selectnodes("/accesos/item/socio"); 
        for (iterator<element> iter = itemlist.iterator(); iter.hasnext();){ 
            element element = iter.next(); 
            system.out.println("numero =" + element.elementtext("numero")); 
        } 
    } catch (documentexception e) { 
        e.printstacktrace(); 
    } 

这段代码 写在java project中,其中user.xml放在src根目录下,类在src/com/jianxin/xml下,很显然运行以上代码是可以出来结果的,但如果把以上代码打包,这个jar包内的目录为
com/jianxin/xml
user.xml
而这里方法内还是去src下去找user.xml,就算把src/从路径中去掉,仍然无法定位到jar中的user.xml上。
这主要是因为jar包是一个单独的文件而非文件夹,绝对不能通过"file:/d:.../user.xml"这种形式来对文件定位,所以即使是相对路径,也无法定位到jar文件内的文件。
那么把xml打入jar包,无论user.xml在哪个目录下,jar包中的类都可以找到,这会是幻想吗?
当然不是,我们可以用类装载器(classloader)来做到:
1)classloader是类加载器的抽象类。它可以运行时动态的获取加载类的运行信息。可以这样说,当我们调用xml.jar中的readxml类时,jvm加载进readxml类,并记录下readxml运行时信息(包括所在jar包的根路径信息)。而classloader类中的方法 可以帮助我们动态获取这些信息:
a.public url getresource(string),查找且有给定名称的资源。
b.public inputstream getresourceasstream(string name),返回指定资源输入流
2)classloader是abstract的,不可能实例化。我们真正写代码的时候,是通过class类中的getresource和getresourceasstream方法 ,这两个方法会委托classloader中的getresource和getresourceasstream方法。现在对上面方法进行重写:

复制代码 代码如下:

public void read(){
 try {
     inputstream is=this.getclass().getresourceasstream("/user.xml");
     document doc = new saxreader().read(is);
  list<element> itemlist =  doc.selectnodes("/accesos/item/socio");
  for (iterator<element> iter = itemlist.iterator(); iter.hasnext();){
   element element = iter.next();
   system.out.println("numero =" + element.elementtext("numero"));
  }
 } catch (documentexception e) {
  e.printstacktrace();
 }
}

这样,打包之前运行是没有问题的,打成包后,依然是可以运行找到数据的~。
在这里我感觉最重要的就是获取class同时会获取jar根目录信息,同时classloader也会有所改变,这点需要注意一下,至于到底是什么改变,目前我也说不上来,只是碰到了这样的问题。所以计划看一本java比较底层的书,以让自己在为别人封装东西的时候更加得心就手,一直停留在应用层次的我们,也是时候深入了解一下jvm了。
最近大部分时间都是在开发,说好的jira可能会更晚些,做的过程中,做是用了一下dwr,下篇对其进行描述~~~