动态网站制作指南



当前位置 > 网站建设学院 > 网络编程 > Java教程 Rss
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket

使用JAXP处理XML文件


发表日期:2008-1-5


JAXP是java API for xml PRocessing的缩写。JAXP API主要的部分在javax.xml.parsers 这个包中。在这个包中,向用户提供了两个最重要的工厂类,SAXParserFactory 和DocumentBuilderFactory,相应地,提供了SAXParser 和DocumentBuilder两个类。

SAX是由XML-DEV定义的;DOM是由W3C定义的。让我们来看看这些API库。

  • javax.xml.parsers
    JAXP API, 定义个SAX和DOM的一个通用接口
  • org.w3c.dom
    定义了DOM中的所有组件
  • org.xml.sax
    定义了SAX的所有API
  • javax.xml.transform
    定义了XSLT API,使用它,你可以将XML转化为一般的可视的页面。

SAX指一种"事件驱动"的处理方式,他对XML文件连续地一个对象一个对象地操作,由于它的这个特点,所以它可以用于服务器端或者对速度有非凡要求的地方。

相比较而言DOM是个使用起来更简单些。他是将所有个XML数据全部读到内存里面,然后使用"树"结构将这些数据组织起来,用户可以对XML的数据进行任意的操作。

至于XSLT,我们在这里就不介绍太多,假如感爱好请参考相应的资料。我们还是先看看SAX。

SAX

SAX的框架轮廓

使用JAXP处理XML文件(图一)

系统是从SAXParserFactory产生parser的实例开始的。一个parser中包含了一个SAXReader对象,当这个parser调用parse方法的时候,这个reader就调用回调方法已实现这个应用;而这些方法呢?是定义在ContentHandler,ErrorHandler,DTDHandler and EntityResolver接口中的。

以下是对SAX API库的概述:

  • SAXParserFactory
    SAXParserFactory是一个根据系统属性生成parser实例的一个对象。
  • SAXParser
    SAXParser是一个定义了不同种类的parser()方法的接口。一般而言,你向parser传XML数据后,使用DefaultHandler再来处理,系统就会调用一些合适的方法来处理XML文件,这样的一种处理方法是最为简单的。
  • SAXReader
    SAXParser包含了一个SAXReader,通常你是不需要关心它的,但是当你要使用SAXReader的getXMLReader()方法的时候,你就需要配置他。简言之,SAXParser就是一个与SAX事件通讯的处理器,这样,你就可以使用自定义的handler。
  • DefaultHandler
    DefaultHandler 实现了 ContentHandler, ErrorHandler, DTDHandler, 和EntityResolver 接口 (当然其中有一些null方法), 假如你感爱好的话,你可以在你的程序中重载它。
  • ContentHandler
    当读到XML的tag时,就会调用到这个接口中的startDocument, endDocument, startElement, 和 endElement 方法。同时,这个接口还定义了characters 和processingInstrUCtion,方法,分别地,当parser碰到XML的element或者inline processing instruction的时候调用。
  • ErrorHandler
    当碰到不同类型的错误的时候分别调用相应的"错误"方法,这些方法包括:error,fatalError和warning。
  • DTDHandler
    该接口所定义的方法只用在处理DTD信息的时候。
  • EntityResolver
    给接口中的resolveEntity方法只在parser碰到URI标识数据的时候才调用。

更具体地api介绍,请参看SAX的官方API文档。

例子:

在我们这个例子中,我们处理一个xml文件,然后将其值set到对象中。这是一个非经常用的使用情况。以下就是我们需要处理的xml文件。

Test.xml

<?xml version="1.0" ?> 
<customers>
  <customer>
    <id>#001</id> 
    <name>Micke</name> 
    <address>Najing</address> 
  </customer>
  <customer>
    <id>#002</id> 
    <name>Car</name> 
    <address>Suzhou</address> 
  </customer>
  <customer>
    <id>#003</id> 
    <name>Jimmy</name> 
    <address>ChengDu</address> 
  </customer>
  <customer>
    <id>#004</id> 
    <name>Henry</name> 
    <address>Xi'an</address> 
  </customer>
</customers>

这是一个非常简单的xml文件,customers中间有数个customer,每一个customer中包含三个属性id, name, address。

根据这个xml文件,我们将Date Object设置如下。

/* 
 * Customers.java
 * Create @ 2004-4-27 22:04:45
 * by Jiabo
 */
import java.util.*;
/**
 * Customers
 * Create @ 2004-4-27 22:04:45
 * by Jiabo
 */
public class Customers {
  private Vector customers;

  public Customers() {
    customers = new Vector();
  }

  public void addCustomer(Customer customer) {
    customers.add(customer);
  }

  public String toString() {
    String newline = System.getProperty("line.separator");
    StringBuffer buf = new StringBuffer();

    for (int i = 0; i < customers.size(); i++) {
      buf.append(customers.elementAt(i)).append(newline);
    }
    return buf.toString(); 
  }
}

class Customer {
  private String id;
  private String name;
  private String address;

  /**
   * @return
   */
  public String getAddress() {
    return address;
  }

  /**
   * @return
   */
  public String getId() {
    return id;
  }

  /**
   * @return
   */
  public String getName() {
    return name;
  }

  /**
   * @param string
   */
  public void setAddress(String string) {
    address = string;
  }

  /**
   * @param string
   */
  public void setId(String string) {
    id = string;
  }

  /**
   * @param string
   */
  public void setName(String string) {
    name = string;
  }
	
  public String toString(){
    return "Customer: ID='" + id + "' Name='" + name + 
      "' Address='" + address + "'";
  }
}

接下来是xml的处理器。

/*
 * Test.java
 * Created on 2004-4-10
 * by Jiabo
 */
import java.util.*;

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
/**
 * Test
 * Create on 2004-4-10 19:20:27
 * by Jiabo
 */
public class Unmarshaller extends DefaultHandler {
  private Customers customers;
  private Stack stack;
  private boolean isStackReadyForText;
  private Locator locator;

  /**
   * init
   */
  public Unmarshaller() {
    stack = new Stack();
    isStackReadyForText = false;
  }
  /**
   * @return customers
   */
  public Customers getCustomers() {
    return customers;
  }
  /**
   * callbacks
   */
  public void setDocumentLocator(Locator rhs) {
    locator = rhs;
  }

  //==========================================
  // SAX DocumentHandler methods
  //==========================================

  public void startElement(
    String uri,
    String sName,
    String qName,
    Attributes attrs) {
      isStackReadyForText = false;

      if (sName.equals("customers")) {
        stack.push(new Customers());
      } else if (sName.equals("customer")) {
        stack.push(new Customer());
      } else if (
        sName.equals("id")
         sName.equals("name")
         sName.equals("address")) {
          stack.push(new StringBuffer());
          isStackReadyForText = true;
      } else {
      }
    }

  public void endElement(String namespaceURI, String sName, String qName){
    isStackReadyForText = false;
    Object temp = stack.pop();

    if (sName.equals("customers")) {
      customers = (Customers) temp;
    } else if (sName.equals("customer")) {
      ((Customers) stack.peek()).addCustomer((Customer) temp);
    } else if (sName.equals("id")) {
      ((Customer) stack.peek()).setId(temp.toString());
    } else if (sName.equals("name")) {
      ((Customer) stack.peek()).setName(temp.toString());
    } else if (sName.equals("address")) {
      ((Customer) stack.peek()).setAddress(temp.toString());
    }
  }

  public void characters(char[] data, int start, int length) {
    if (isStackReadyForText == true) {
      ((StringBuffer) stack.peek()).append(data, start, length);
    } else {
    }
  }
}

在这里我们处理xml文件的思路非常简单,就是使用一个栈,碰到"<"表示element的开始,然后就看与我们既定的Data Object的名字是否相符合,符合就new一个该对象,并将其压栈;不符合就什么都不做,sax的处理框架就会自己去处理下一个element。而当碰到"/>"的时候我们还是看的他名字与DataObject的名字是否相符,相符合的话就出栈,然后set进对象里面。如此循环,就处理完了我们上面那个简单得xml文件。

我们需要做的事情就只有这些。其他如何处理的,handler回自己调用相应的startElement,endElement等方法去处理。

以下是程序的入口:

/* 
 * main.java
 * Create @ 2004-4-27 22:18:41
 * by Jiabo
 */
import java.io.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
/**
 * main
 * Create @ 2004-4-27 22:18:41
 * by Jiabo
 */
public class Main {
  public static void main(String args[]) {

    Customers customers = null;
    if (args.length != 1) {
      System.err.println("Usage: cmd filename");
      System.exit(1);
    }
    try {
      Unmarshaller handler = 	new Unmarshaller();
      SAXParserFactory factory = SAXParserFactory.newInstance(); 
      SAXParser saxParser = factory.newSAXParser();
			
      File file = new File(args[0]);
      InputSource src = new InputSource(new FileInputStream(file));
      saxParser.parse( src ,handler); 

      customers = handler.getCustomers();
    } catch (Throwable t) {
      t.printStackTrace();
    }

    System.out.println(customers);
  }
}

如前面所述,通过一个工厂方法得到一个SAXParser的实例,然后就可以编译这个xml文件了。这样你就可以得到如下结果:

Customer: ID ='#001' Name='Micke' Address='Najing' 
Customer: ID ='#002' Name='Car' Address='Suzhou' 
Customer: ID ='#003' Name='Jimmy' Address='ChengDu' 
Customer: ID ='#004' Name='Henry' Address='Xi'an'

Sax的系统框架中还有其他得好些方法,读者不妨试试他们是如何使用的,这对以后实战处理xml文件会有很大的方便。


关注此文的读者还看过:
·2012-2-7 21:41:42 项目经理需知的Java技术问题
·2012-2-7 21:41:38 用户登录的验证完整程序
·2012-2-7 21:41:31 选取合适的dHtml Grid方案
·2012-2-7 21:40:56 log 方法
·2012-2-7 21:40:51 Java中的Hashtable
·2012-2-7 21:40:46 Eclipse插件ANTLR Studio 发布开源免费版本
·2012-2-7 21:40:45 Eclipse发布AspectJ 5 正式版
·2012-2-7 21:40:30 测试要考虑成本、粒度和角度问题
·2012-2-7 21:40:29 如何迅速成为Java高手[Tomjava原创]
站长推荐 PS笔刷下载 在线翻译 系统进程 广告代码

  发表评论
姓 名: 验证码:
内 容:
教程搜索服务
项目外包信息
·找长期合作的网页设计师(切图+
·SNS 网站开发
·云南大蓄文化传播有限公司网站设
·药品代购网站
·FLASH网站汉化
·求高手帮我设计一个减肥产品网站
·flash首页制作(已有设计图)
·寻求长期外包人员
·网页页面修改
·北京地区 flash动画合作
·佛山网站建设+263企业邮箱找我。
·ecshop+Discuz! X2+ Home会员整
·寻找网站建设团队或者个人合伙
·LOGO设计外包
·企业网后台程序外包
发布信息 浏览信息
邮件订阅服务
输入你的邮件地址,你将不会错过任何关于<Java教程>的内容


网络编程文章分类
ASP教程
ASP实例
ASP技巧
ASP文摘
PHP教程
PHP技巧
PHP实例
PHP文摘
JSP教程
JSP技巧
JSP实例
JSP文摘
ASP.NET教程
ASP.NET技巧
ASP.NET实例
ASP.NET应用
xml教程
xsl教程
xml技巧
C#教程
C#应用
Delphi教程
Perl教程
Shell教程
Ajax教程
Visual Basic教程
Java教程
J2EE/J2ME教程
C/C++教程
移动解决方案
移动短信技术
移动行业动态
软件工程
WordPress
Android开发
站长工具:Google PR查询|Alexa排名查询|网站速度测试|CSS在线编辑器|OPEN参数生成器|弹出式窗口代码产生器|密码登录生成器|在线按钮生成器|Meta标签生成器|邮箱图标在线生成|多色彩特效字代码生成器|网页代码调试器|在线FTP登陆|Flash取色器|配色代码对照表|配色辞典|CSS生成器|CSS在线压缩|广告代码|框架网页代码生成器|js/vbs加密|md5加密|进制转换|UTF-8 转换工具|在线调色板|Html转换js|Html转换asp|Html转换php|Html转换perl
实用工具:汉字翻译拼音|拼音字典|在线翻译|天气预报|火星文|在线网速测试|符号对照表|个税计算|理财工具|黄金价格|购房银行按揭利率计算|汇率查询|经典小工具|汉字简繁转换|普通单位换算|公制单位换算|生辰老黄历|国内电话区号|国家代码与域名缩写|文字加密解密|元素周期表|健康查询|世界时间|全国各地车牌查询|全国车辆交通违章查询|万年历|二十四节气|汉字横竖排版|手机号码查询|计算器|ip搜索
广告刊登 | 版权声明 | 联系我们 | 加入收藏 | RSS订阅
Copyright © 2000-2012 www.knowsky.com All rights reserved | 沪ICP备05001343号