三 java解析xml文件

3.1 java与xml的共同点
有很多共同点,比如跨平台,与厂商无关,目前为止java对xml的解析比其他语言更完善(java是支持xml最好的语言).
3.2 java解析xml有两种方式
1)DOM:文本对象模型(Document Object Model)
2)SAX: 基于xml的简单API (Simple API for XML )
3)嵌入式设备中常用sax进行解析.例如 android 中就是使用sax作为解析xml文件工具的.android中还有另外一种叫做Pull解析.
3.3 JDOM/DOM4J
目前常用的两种解析xml文件的API 
3.4 DOM解析
解析xml文件是以树状结构进行解析的.DOM在解析xml的时候会将整个xml内容解析出来,以元素描绘每个节点和嵌套关系,并载入内存.
1) 关键字 :树(document)
2) 优点:把xml文件在内存中构建树形结构,可以遍历和修改节点,因为它知道节点的所有关系.
3) 缺点:因为解析时,就将整个xml文件载入到内存,所以解析过程长,内存开销大.
3.5 sax解析
解析xml文件,就是把xml文件作为输入流,触发标记开始内容开始,标记结束等动作.
1) 关键字 流(stream)
2) 优点: 解析可以立即开始,速度快,没有内存压力.
3) 缺点: 不能对节点进行修改.
3.6 案例:使用dom4j包的核心api解析xml文件.
我们使用dom工具,来自dom4j,非常流行的用于解析xml的dom工具,还有一种常用的叫做jdom,解析步骤:
1) 创建用于解析xml文件的读取器 SAXReader;
2) 使用SAXReader 读取指定的输入流来解析xml文件
3)第二步的方法会返回一个Document对象,描述整个文档,通过该文档对象获取根标签(标记) Root;
4) 根据树的组成形式,逐一解析.

db_info.xml文件:如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jdbc[
<!ELEMENT jdbc (oracle*,mysql*)>
<!ELEMENT oracle ((url|uri),driver,username,password)>
<!ELEMENT mysql (url,driver,username,password)>
<!ELEMENT uri (#PCDATA)>
<!ELEMENT url (#PCDATA)>
<!ELEMENT driver (#PCDATA)>
<!ELEMENT username (#PCDATA)>
<!ELEMENT password (#PCDATA)>
<!ATTLIST oracle user CDATA "user">
<!ATTLIST oracle id CDATA "xxx">
]>
<jdbc>
<oracle user="user" id="xxx">
<url>jdbc:oracle:thin:@localhost:1521:xe</url>
<driver>oracle.jdbc.driver.OracleDriver</driver>
<username>orcl</username>
<password>orcl</password>
</oracle>

<oracle user="admin">
<url>jdbc:oracle:thin:@localhost:1521:xe</url>
<driver>oracle.jdbc.driver.OracleDriver</driver>
<username>orcl</username>
<password>orcl</password>
</oracle>

<mysql>
<url>jdbc:mysql://localhost:3306/test</url>
<driver>com.mysql.jdbc.Driver</driver>
<username>root</username>
<password>root</password>
</mysql>
</jdbc>


step1:创建DBInfo类
package com.wst.utils;


public class DBInfo {
private String url;
private String driver;
private String username;
private String password;
private String dbName;//数据库连接名
private String attUser;//数据库标签的属性user
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getAttUser() {
return attUser;
}
public void setAttUser(String attUser) {
this.attUser = attUser;
}

}


step2: 创建XMLUtils工具类,用于解析xml文件.
package com.wst.utils;


import java.awt.image.DataBufferByte;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;


public class XMLUtils {
/**
* 定义常量,用于描述当前解析的xml中出现的标签名
*/
private static final String ELEMENT_JDBC="jdbc";
private static final String ELEMENT_ORACLE="oracle";
private static final String ELEMENT_MYSQL="mysql";
private static final String ELEMENT_URL="url";
private static final String ELEMENT_DRIVER="driver";
private static final String ELEMENT_USERNAME="username";
private static final String ELEMENT_PASSWORD="password";
private static final String ATTRIBUTE_USER="user";

/**
* 解析xml文件,将xml配置的所有数据库连接信息返回
* @param input:因为我们要使用dom去解析xml文件,那么一定会通过输入流去读取xml文件中的数据,无论这个文件来自网络
* 还是本地文件,我们在程序中都是通过输入流的形式来读取的.
* @return
*/
public static List<DBInfo> xmlToDBInfo(InputStream input){
//1. 使用dom4j需要导包 :  dom4j-1.6.1.jar
SAXReader reader=new SAXReader();
/**
* 解析xml文件前调用该方法,该方法默认值是false,设置为true的作用是检查xml文件的合法性,验证DTD
*/
reader.setValidation(false);//此处建议先false,否则DTD稍有错误就将报错.
//2.导包 org.dom4j.Document
Document document;
try{
document=reader.read(input);//读取并解析文件
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException("数据读取错误!",e);
}
//3.导包: org.dom4j.Element
Element root=document.getRootElement();
/**
* root.getName() 用于获取当前标签的名字,这里应该是jdbc.
*/
if(!"jdbc".equals(root.getName())){
throw new RuntimeException("数据格式错误,根应该是:"+ELEMENT_JDBC);
}
//4.逐一解析
/**
* root.elements() 该方法获取root元素下的所有子元素并以集合的形式返回.
* root.element(String name) 获取指定名字的子元素
* root.elements(String name) 获取指定名字的所有子元素.
*/
List<Element> childList=root.elements();
/**
* 将oracle元素和mysq元素保存的内容存放到相应的DBInfo对象中,再将这些对象存入到一个集合并返回,最终完成解析工作.
*/
List<DBInfo> infos=new ArrayList<DBInfo>();
for(Element child:childList){
//将oracle或者mysql标签转化为DBInfo对象并存入集合infos
DBInfo info=toDBInfo(child);
infos.add(info);
}
return infos;

}


private static DBInfo toDBInfo(Element element) {
DBInfo info=new DBInfo();
// Element urlElement=element.element(ELEMENT_URL);//先拿到标签,再拿标签中的内容
// String url=urlElement.getText();
String url=element.elementText(ELEMENT_URL);//同上两步,直接获取子元素文本.
String driver=element.elementText(ELEMENT_DRIVER);
String username=element.elementText(ELEMENT_USERNAME);
String password=element.elementText(ELEMENT_PASSWORD);
String attUser=element.attributeValue(ATTRIBUTE_USER);//获取标签的属性值
String dbName=element.getName();//获取当前标签的名字
info.setAttUser(attUser);
info.setDbName(dbName);
info.setDriver(driver);
info.setPassword(password);
info.setUrl(url);
info.setUsername(username);
return info;
}
}

step3:测试:
package com.wst.utils;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.List;


public class XmlToJavaTest {


public static void main(String[] args) throws FileNotFoundException {
FileInputStream fis=new FileInputStream("db_info.xml");
List<DBInfo> infos=XMLUtils.xmlToDBInfo(fis);
for(DBInfo info:infos){
System.out.println("db_name:"+info.getDbName());
System.out.println("url:"+info.getUrl());
System.out.println("driver:"+info.getDriver());
System.out.println("username:"+info.getUsername());
System.out.println("attUser:"+info.getAttUser());
System.out.println("");
}
}


}


step4: 测试结果
db_name:oracle
url:jdbc:oracle:thin:@localhost:1521:xe
driver:oracle.jdbc.driver.OracleDriver
username:orcl
attUser:user


db_name:oracle
url:jdbc:oracle:thin:@localhost:1521:xe
driver:oracle.jdbc.driver.OracleDriver
username:orcl
attUser:admin


db_name:mysql
url:jdbc:mysql://localhost:3306/test
driver:com.mysql.jdbc.Driver
username:root
attUser:null


3.7案例:使用dom4j包的核心API 写入xml文件
将数据写入xml文件的步骤
1)创建一个文档对象document
2)向文档对象中添加根元素
3)向根元素中按照需求添加子元素,最终构成xml的树状结构.
4)将根元素写出(等同于将整个书写出)这样整个结构就转化为xml形式写出了.

step1:在XMLUtils工具类中,添加writeDBInfosToXml()方法.
/**
* 将给定的一组数据(model)以xml的格式通过输出流写出.
* @param out
* @param infos
* @throws Exception
*/
public static void  writeDBInfosToXml(OutputStream out,List<DBInfo> infos) throws Exception {
//1.创建文档对象
Document document=DocumentHelper.createDocument();
//2.添加根元素
/**
* Document的addElement(String name)会向文档对象添加名称为参数的根元素,该方法有返回值,返回值为添加的根元素
* 对象Element.
*/
Element root=document.addElement(ELEMENT_JDBC);
//3.添加子元素
/**
* 向根元素中添加子元素,添加多少个子元素时由给定的数据决定的.
*/
for(DBInfo info:infos){
Element element =toDBInfoElment(info);
root.add(element);
}
//4.将根元素写出
XMLWriter writer=new XMLWriter();
writer.write(root);//将根元素写出,就相当于将整个树写出了,以XML的格式写出的.
writer.flush();//清空缓存
writer.close();
System.out.println("写出完毕!");
}
step2:在XMLUtils工具类中,添加toDBInfoElment()方法
/**
* 将DBInfo转换为元素Element
* @param info
* @return
*/
public static Element toDBInfoElment(DBInfo info) {
//1.创建一个空的Element对象,该对象仅代表oracle或mysql元素,没有子元素和属性
Element element=DocumentHelper.createElement(info.getDbName());
//2.添加子元素,如URL,driver等元素
// Element url=DocumentHelper.createElement(ELEMENT_URL);
// element.add(url);
Element url=element.addElement(ELEMENT_URL);//等同于上两步
url.setText(info.getUrl());
// Element driver=element.addElement(ELEMENT_DRIVER);
// driver.setText(info.getUrl());
element.addElement(ELEMENT_DRIVER).setText(info.getDriver());//又等同于上两步.
element.addElement(ELEMENT_USERNAME).setText(info.getUsername());
element.addElement(ELEMENT_PASSWORD).setText(info.getPassword());
//3.为当前元素加属性,如user="user"
element.addAttribute(ATTRIBUTE_USER, info.getAttUser());
return element;
}

step3: 测试
package com.wst.utils;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;




public class JavaToXmlTest {
public static void main(String[] args) throws Exception {
FileInputStream fis=new FileInputStream("db_info.xml");
List<DBInfo> infos=XMLUtils.xmlToDBInfo(fis);
File file=new File("db_infoCopy.xml");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fos=new FileOutputStream(file);
XMLUtils.writeDBInfosToXml(fos, infos);
}
}


step4: 测试结果
<jdbc><oracle user="user"><url>jdbc:oracle:thin:@localhost:1521:xe</url><driver>oracle.jdbc.driver.OracleDriver</driver><username>orcl</username><password>orcl</password></oracle><oracle user="admin"><url>jdbc:oracle:thin:@localhost:1521:xe</url><driver>oracle.jdbc.driver.OracleDriver</driver><username>orcl</username><password>orcl</password></oracle><mysql><url>jdbc:mysql://localhost:3306/test</url><driver>com.mysql.jdbc.Driver</driver><username>root</username><password>root</password></mysql></jdbc>
注意事项:XML长被用于在不同系统间传递数据使用.还有一种比较常见的是json.前两个以字符串传递.还有一个比较常见的是goole prtocol buffer以字节传递.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值