- 浏览: 307944 次
- 性别:
- 来自: 成都
文章分类
- 全部博客 (118)
- VS2008 (2)
- JAVA (34)
- AJAX (1)
- C# (1)
- Flex (16)
- FMS (6)
- SQLSERVER (1)
- ORACLE (1)
- Quartz (1)
- struts2 (1)
- java数据结构 (1)
- java设计模式 (3)
- JSF (0)
- web (2)
- jbpm4 (4)
- J2EE (1)
- webservice (2)
- javascript (8)
- spring (3)
- lucene (0)
- linux (9)
- ibatis (1)
- JPA (2)
- 外挂 (0)
- VB (0)
- Hibernate (1)
- OSGI (8)
- EXT (4)
- Maven (1)
- SpringSecurity (0)
- activiti (0)
- 项目开发 (0)
- 项目管理 (7)
- android (0)
- FFMPEG (1)
- C (2)
- eclipse (1)
最新评论
-
默默得守候在你的身边:
给力
java与Delphi写的dll交互 -
默默得守候在你的身边:
java与Delphi写的dll交互 -
fuguitong:
[url][url][url][url][url][url][ ...
doc转swf -
baidu_25402161:
到结束的时候一直 Can't delete processIn ...
一个请假单流程的实现(struts2.1.8+spring2.5+hibernate3集成jbpm4.3) -
lohaoo1:
nice!
java面包屑导航制作
练习解析配置文件,所以找了个真实的配置文件来进行解析,突然发现自己面向对象的思维欠缺,结果写成面向过程的了,哈哈。用到的jar包dom4j-1.6.1.jar和jaxen-1.1.1.jar,commons-logging.jar,log4j-1.2.15.jar
ibatis配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <!-- 学生实体 --> <sqlMap namespace="Student"> <typeAlias alias="Student" type="org.forever.xxxx.domain.Student" /> <!-- 可以配置多个结果映射信息描述 --> <resultMap id="StudentResult" class="Student"> <result property="id" column="ID_" /> <result property="name" column="NAME_" /> <result property="sex" column="SEX_" /> <result property="age" column="AGE_" /> <result property="grade" column="GRADE_" /> <result property="clazz" column="CLASS_" /> </resultMap> <!-- 多条件查询 --> <select id="findByMap" parameterClass="java.util.Map" resultMap="StudentResult"> SELECT * FROM STUDENT_ WHERE STUDENT_.GRADE_=#grade# AND STUDENT_.CLASS_=#class# AND STUDENT_.NAME_ LIKE '%$name$%' AND STUDENT_.AGE_ BETWEEN #start_age# AND #end_age# AND STUDENT_.SEX_ IN ('男','女') ORDER BY STUDENT_.NAME_ ASC,STUDENT_.AGE_ ASC </select> <!-- 处理条件的模板sql语句 --> <sql id="condition_sql"> <!-- 条件集合不为null时说明有附加条件 --> <isNotNull property="conditions"> <!-- 迭代条件集合,还有其他条件的解析,自己补充吧 ,这种条件可以写成模板sql,让统计语句重复使用--> <iterate property="conditions" prepend=" AND " conjunction=" AND "> <!-- 等于条件解析 --> <isEqual property="${conditions[].operation}" compareValue="EQ"> <![CDATA[ ($conditions[].propertyName$ = #conditions[].propertyValue#) ]]> </isEqual> <!-- 大于等于--> <isEqual property="${conditions[].operation}" compareValue="GE"> <![CDATA[ ($conditions[].propertyName$ >= #conditions[].propertyValue#) ]]> </isEqual> <!-- 小于等于--> <isEqual property="${conditions[].operation}" compareValue="LE"> <![CDATA[ ($conditions[].propertyName$ <= #conditions[].propertyValue#) ]]> </isEqual> <!-- 模糊条件解析 --> <isEqual property="${conditions[].operation}" compareValue="LIKE"> <![CDATA[ ($conditions[].propertyName$ LIKE '%'||#conditions[].propertyValue#||'%') ]]> </isEqual> <!-- 范围条件解析 --> <isEqual property="${conditions[].operation}" compareValue="BETWEEN"> <![CDATA[ ($conditions[].propertyName$ BETWEEN #conditions[].propertyValue[0]# AND #conditions[].propertyValue[1]#) ]]> </isEqual> <!-- in条件解析 --> <isEqual property="${conditions[].operation}" compareValue="IN"> <![CDATA[ ($conditions[].propertyName$ IN ]]> <iterate open="(" close="))" conjunction="," property="${conditions[].propertyValue}"> #conditions[].propertyValue[]# </iterate> </isEqual> </iterate> </isNotNull> </sql> <!-- 分页查询单个对象的信息 --> <select id="queryByStudent" parameterClass="Student" resultMap="StudentResult"> <![CDATA[ SELECT * FROM ( SELECT ROWNUM NUM,STUDENT_.* FROM STUDENT_ WHERE 1=1 AND (ROWNUM<=#currentPage#*#pageSize#) ]]> <include refid="condition_sql"/> <!-- 排序条件处理 --> $orderSql$ <![CDATA[ ) WHERE NUM >(#currentPage#-1)*#pageSize# ]]> </select> <!-- 分页统计查询 --> <select id="queryPageCount" parameterClass="Student" resultClass="int"> SELECT COUNT(*) FROM STUDENT_ WHERE 1=1 <include refid="condition_sql"/> </select> <!-- 单个参数配置 --> <select id="findByNameStudent" parameterClass="string" resultMap="StudentResult"> SELECT * FROM STUDENT_ WHERE STUDENT_.NAME_=#name# </select> <!-- 根据学生id查询 --> <select id="findByIdStudent" parameterClass="int" resultMap="StudentResult"> SELECT * FROM STUDENT_ WHERE STUDENT_.ID_=#id# </select> <!-- 更新一条记录 --> <update id="updateStudent" parameterClass="Student"> UPDATE STUDENT_ SET STUDENT_.AGE_=#age#,STUDENT_.NAME_=#name#,STUDENT_.CLASS_=#clazz#,STUDENT_.GRADE_=#grade#,STUDENT_.SEX_=#sex# WHERE STUDENT_.ID_ = #id# </update> <!-- 删除一条记录 --> <delete id="deleteStudent" parameterClass="int"> DELETE STUDENT_ WHERE STUDENT_.ID_ = #id# </delete> <!-- 批量删除 --> <delete id="batchDelete" parameterClass="java.util.List"> DELETE STUDENT_ WHERE STUDENT_.ID_ IN <iterate conjunction="," open="(" close=")"> #value[]# </iterate> </delete> <!-- 添加一条记录,参数类型为Student --> <insert id="saveStudent" parameterClass="Student"> <!-- 获取序列的下一个值 keyProperty为实体的属性--> <selectKey keyProperty="id" resultClass="int"> SELECT SEQ_STUDENT_ID.NEXTVAL AS SID FROM DUAL </selectKey> <!-- #属性#字段 --> <![CDATA[ INSERT INTO STUDENT_( ID_, NAME_, SEX_, AGE_, GRADE_, CLASS_ ) VALUES( #id#, #name#, #sex#, #age#, #grade#, #clazz# ) ]]> </insert> <!-- 查询所有信息 --> <select id="findAllStudent" resultMap="StudentResult"> SELECT * FROM STUDENT_ </select> </sqlMap>
代码没有经过优化的:
package org.forever.xml; import java.io.InputStream; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.dom4j.tree.DefaultCDATA; import org.dom4j.tree.DefaultText; import org.forever.pagination.Condition; import org.forever.pagination.Operation; import org.forever.pagination.Order; import org.forever.pagination.OrderType; import org.forever.xxxx.domain.Student; public class StudentXml { private static Log log = LogFactory.getLog(StudentXml.class); private static Document doc; public static void main(String[] args) throws Exception { // 以下是解析ibatis的一个xml配置文件 SAXReader reader = new SAXReader(); InputStream inputStream = StudentXml.class.getClassLoader() .getResourceAsStream( "org/forever/xxxx/domain/Student.ibatis.xml"); doc = reader.read(inputStream);// 获取文档对象 // 以下是对各个方法的解析 List<Object> param_list = new ArrayList<Object>();// 搜集参数值的集合 Object param;// 单个参数声明 // 查询id为findAllStudent的元素 Element element = getSingleNode("/sqlMap/select[@id='findAllStudent']"); element = getSingleNode("/sqlMap/select[@id='findByIdStudent']"); param = 2;// 模拟findByIdStudent方法的参数 element = getSingleNode("/sqlMap/select[@id='findByNameStudent']"); param = "admin";// 模拟findByNameStudent方法的参数 element = getSingleNode("/sqlMap/select[@id='findByMap']"); Map<String, Object> map = new HashMap<String, Object>(); map.put("grade", "一年级"); map.put("class", "二班"); map.put("start_age", 14); map.put("end_age", 18); map.put("name", "陈均"); param = map;// 模拟findByMap方法的参数 element = getSingleNode("/sqlMap/select[@id='queryByStudent']"); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date startTime = dateFormat.parse("2010-02-01"); Date endTime = dateFormat.parse("2010-03-02"); //条件集合 List<Condition> conditions = Arrays.asList( new Condition("stuGrade", "一年级",Operation.EQ), new Condition("stuAge",12,Operation.GE), new Condition("stuAge",19,Operation.LE), new Condition("stuClass", "二班", Operation.EQ), new Condition("stuName", "stor", Operation.LIKE), new Condition("stuAge", new Object[] { 14, 18 }, Operation.BETWEEN), new Condition("stuSex", Arrays.asList("男","女"),Operation.IN), new Condition("stuTime",new Object[]{startTime,endTime},Operation.BETWEEN) ); Student student = new Student(); student.setPageSize(2);//每页2条 student.setCurrentPage(2);//查看第2页 student.setConditions(conditions); List<Order> orders = Arrays.asList( new Order("stuName", OrderType.ASC), new Order("stuAge", OrderType.ASC) ); student.setOrders(orders); param = student;//模拟queryByStudent方法的参数 //模拟批量删除 // element = getSingleNode("/sqlMap/delete[@id='batchDelete']"); // param = Arrays.asList(2,3,4,5); //动态sql解析 //元素、属性、文本、命名空间、处理指令、注释以及文档 StringBuffer qlString = new StringBuffer(); parseEC(element, qlString,param,param_list); log.info(qlString.toString()); log.info(param_list.size()); } //解析#号 private static void parseJH(StringBuffer sb,Object param,List<Object> p_list) throws Exception{ String str = "#";// #?#形式的解析 int start = sb.indexOf(str, 0);// 第一次#号出现的起始位置 int end = sb.indexOf(str, start + 1);// 第一次#号出现的结束位置 while (start != -1 && end != -1) {// 可能有多个#号 String property = sb.substring(start + 1, end);// 提取##之间的名字 //可能出现conditions[].propertyValue这种写法 //去掉即可 //首先用.进行分割 String[]p = property.split("\\."); if(p.length>1){//说明存在. //取第二个单元的内容,这里假设不会出现conditions[].propertyValue.?这种,也没意义 property = p[1]; } //还可能出现property = propertyValue[0]这种 int start_ = property.indexOf("["); Object value = null; if(isPrimitive(param)){//如果是基本类型 value = param; }else if(param instanceof Map<?,?>){ value = ((Map)param).get(property); }else if(start_!=-1){ int index = Integer.parseInt(property.substring(start_+1, start_+2));//获取下标 property = property.replaceAll("\\["+index+"\\]", "");//去掉[?] Field field = getField(param, property); field.setAccessible(true); value = field.get(param); p_list.add(((Object[])value)[index]); }else{ //反射获取值 Field field = getField(param, property); field.setAccessible(true); value = field.get(param); p_list.add(value); } sb.replace(start, end + 1, "?");// 把语句中的#?#符号替换成?号 start = sb.indexOf(str, start);// 获取下一次#号出现的起始位置 end = sb.indexOf(str, start + 1);// 获取下一次#号出现的结束位置 }//end } //解析$符号 private static void parse$(StringBuffer sb,Object param,List<Object> p_list) throws Exception{ String str = "$"; int start = sb.indexOf(str, 0);// 第一次$号出现的起始位置 int end = sb.indexOf(str, start + 1);// 第一次$号出现的结束位置 while (start != -1 && end != -1) {// 可能有多个$号 String property = sb.substring(start + 1, end);// 提取$$之间的名字 //可能出现$conditions[].propertyName$这种写法 //去掉即可 //首先用.进行分割 String[]p = property.split("\\."); if(p.length>1){//说明存在. //取第二个单元的内容,这里假设不会出现conditions[].propertyValue.?这种,也没意义 property = p[1]; } Object value = null; if(isPrimitive(param)){//如果是基本类型 value = param; }else if(param instanceof Map<?,?>){ value = ((Map)param).get(property); }else{ //反射获取值 Field field = getField(param, property); field.setAccessible(true); value = field.get(param); } sb.replace(start, end + 1, value.toString());// 把语句中的$?$符号替换成具体的值 start = sb.indexOf(str, start);// 获取下一次$号出现的起始位置 end = sb.indexOf(str, start + 1);// 获取下一次$号出现的结束位置 }//end } //递归解析 private static void parseEC(Element element, StringBuffer sb,Object param,List<Object> p_list) throws Exception { for (Object obj : element.content()) { if(obj instanceof DefaultText){ DefaultText dt = (DefaultText)obj; log.info("文本元素:" + dt.getNodeTypeName()); log.info("文本内容:" + dt.getText()); sb.append(" " + dt.getText().trim() + " "); //如果是空文本,本次操作是可以略过的 if("".equals(dt.getText().trim())){ continue; } parseJH(sb, param, p_list); // 还有种$?$形式的解析,这种解析直接将值赋予语句中,和##的解析差不多 parse$(sb, param, p_list); }else if(obj instanceof Element){ Element e = (Element)obj; log.info("元素标签:"+e.getNodeTypeName()); String name = e.getName(); if(name.equals("include")){//如果是include String refid = e.attributeValue("refid");//获取引用的sqlid //找到该元素的模板进行解析,发现是个递归操作 Element sql_e = getSingleNode("/sqlMap/sql[@id='"+refid+"']"); parseEC(sql_e, sb,param,p_list);//递归处理该元素 }else if("isNotNull".equals(name)){//如果是不为null标签元素 String property = e.attributeValue("property"); //反射获取指定的属性 Field field = getField(param, property); field.setAccessible(true); Object value = field.get(param); log.info("属性"+property + (value==null?"为空,不满足条件":"不为空,满足条件")); if(value!=null){ //递归遍历子元素 parseEC(e, sb, param,p_list); } }else if("iterate".equals(name)){//如果遇到迭代标签 String property = e.attributeValue("property");//获取迭代的属性 String prepend = e.attributeValue("prepend");//获取迭代前缀字符串 String open = e.attributeValue("open"); String close = e.attributeValue("close"); String conjunction = e.attributeValue("conjunction"); if(property==null){ property = ""; } //去掉${,},[] property = property.replace("$", "") .replace("{", "") .replace("}", "") .replace("[", "") .replace("]", ""); //以.分割数组 String[]nameArray = property.split("\\."); //从第二个名字开始 String pn1 = property; if(nameArray.length>1){ pn1 = nameArray[1]; } List list = null; if(param instanceof java.util.List<?>){ list = (List) param; }else{ Field field = getField(param, pn1); //假设迭代标签只支持list类型的 field.setAccessible(true); list = (List) field.get(param); } log.info(list.size()); if(open!=null && close!=null && conjunction!=null){ sb.append(open); for (Object object : list) { sb.append("?" + conjunction); p_list.add(object); } sb.delete(sb.length()-1,sb.length());//去掉最后一个多余的 sb.append(close); }else{ //遍历list for (Object object : list) { sb.append(prepend); parseEC(e, sb, object, p_list); } } }else if("isEqual".equals(name)){//如果是比较标签 String property = e.attributeValue("property");//获取比较的属性 String compareValue = e.attributeValue("compareValue");//比较的值 //去掉${,},[] property = property.replace("$", "") .replace("{", "") .replace("}", "") .replace("[", "") .replace("]", ""); //以.分割数组 String[]nameArray = property.split("\\."); //从第二个名字开始 String pn1 = nameArray[1]; //反射获取改字段的值 Field field = getField(param, pn1); //假设迭代标签只支持list类型的 field.setAccessible(true); if(compareValue.equals(field.get(param).toString())){//如果满足等于条件 //递归解析里面的内容 parseEC(e, sb, param, p_list); } } }else if(obj instanceof DefaultCDATA){ DefaultCDATA cdata = (DefaultCDATA)obj; log.info("cdata元素:"+cdata.getNodeTypeName()); log.info("cdata的内容为:" + cdata.getText().trim()); sb.append(" " + cdata.getText().trim() + " "); parseJH(sb, param, p_list); // 还有种$?$形式的解析,这种解析直接将值赋予语句中,和##的解析差不多 parse$(sb, param, p_list); } } } private static Field getField(Object param, String property) throws NoSuchFieldException { Field field; try { field = param.getClass().getDeclaredField(property); } catch (Exception e1) { //去父类中找寻,在此支持一级父类找寻,如果多级,那就递归呗 field = param.getClass().getSuperclass().getDeclaredField(property); } return field; } //是否是基本类型 public static boolean isPrimitive(Object param){ //等等..... if(param.getClass().isPrimitive() || param instanceof String || param instanceof Integer){ return true; } return false; } public static Element getSingleNode(String xpath) { return (Element) doc.selectSingleNode(xpath); } }
log4j配置文件:
##LOGGERS## log4j.rootLogger=INFO,console ##APPENDERS## log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=d\:\\log.txt log4j.appender.file.MaxFileSize=1024KB ##LAYOUTS## log4j.appender.console.layout=org.apache.log4j.SimpleLayout log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm} %t %p- %m%n
例子中所用到的其他类:
PageInfo
package org.forever.pagination; import java.io.Serializable; import java.util.List; //分页信息 public class PageInfo implements Serializable { private static final long serialVersionUID = -2013522911148457717L; private int currentPage = 1;// 当前页 private int totalPage = 0;// 总页数 private int totalItems = 0;// 总条数 private int pageSize = 10;// 每页显示多少条 protected List<Condition> conditions;// 条件集合 protected List<Order> orders;// 排序集合 private String orderSql="";// 排序拼接语句 public PageInfo() { } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public int getTotalItems() { return totalItems; } public void setTotalItems(int totalItems) { this.totalItems = totalItems; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public List<Condition> getConditions() { return conditions; } public void setConditions(List<Condition> conditions) { this.conditions = conditions; } public List<Order> getOrders() { return orders; } public void setOrders(List<Order> orders) { this.orders = orders; StringBuffer order = new StringBuffer(); if (orders != null && orders.size() > 0) { order.append(" ORDER BY "); for (Order item : orders) { String propertyName = item.getPropertyName(); switch (item.getOrderType()) { case ASC: order.append(propertyName + " ASC,"); break; case DESC: order.append(propertyName + " DESC,"); break; default: break; } } //去掉多余的逗号 order.replace(order.length() - 1, order.length(), ""); } setOrderSql(order.toString()); } public String getOrderSql() { return orderSql; } public void setOrderSql(String orderSql) { this.orderSql = orderSql; } }
条件Condition类:
package org.forever.pagination; //条件操作 public class Condition { private String propertyName;// 属性名 private Object propertyValue;// 属性值 private Operation operation;// 操作符号 public Condition() { } public String getPropertyName() { return propertyName; } public void setPropertyName(String propertyName) { this.propertyName = propertyName; } public Object getPropertyValue() { return propertyValue; } public void setPropertyValue(Object propertyValue) { this.propertyValue = propertyValue; } public Operation getOperation() { return operation; } public void setOperation(Operation operation) { this.operation = operation; } public Condition(String propertyName, Object propertyValue, Operation operation) { this.propertyName = propertyName; this.operation = operation; this.propertyValue = propertyValue; // 在这里处理属性值 } }
package org.forever.pagination; //操作类型 public enum Operation { IN, EQ, GT, LT, NE, GE, LE, BETWEEN, LIKE }
package org.forever.pagination; public class Order { private String propertyName;// 属性名 private OrderType orderType;// 排序类型 public Order() { } public Order(String propertyName, OrderType orderType) { super(); this.propertyName = propertyName; this.orderType = orderType; } public String getPropertyName() { return propertyName; } public void setPropertyName(String propertyName) { this.propertyName = propertyName; } public OrderType getOrderType() { return orderType; } public void setOrderType(OrderType orderType) { this.orderType = orderType; } }
package org.forever.pagination; public enum OrderType { ASC, DESC }
解析queryByStudent方法的结果:
INFO - SELECT * FROM ( SELECT ROWNUM NUM,STUDENT_.* FROM STUDENT_ WHERE 1=1 AND (ROWNUM<=?*?) AND (stuGrade = ?) AND (stuAge >= ?) AND (stuAge <= ?) AND (stuClass = ?) AND (stuName LIKE '%'||?||'%') AND (stuAge BETWEEN ? AND ?) AND (stuSex IN (?,?)) AND (stuTime BETWEEN ? AND ?) ORDER BY stuName ASC,stuAge ASC ) WHERE NUM >(?-1)*? INFO - 15
发表评论
-
OSGI学习
2012-03-18 18:01 0http://www.blogjava.net/zhenyu3 ... -
OSGI学习笔记(七)
2012-03-17 23:58 1693SpringDM初步使用(二) 介绍哈官方的第二个例子 ... -
ubuntu10.04下nexus和maven的安装及配置
2012-03-14 16:14 2510前提要有jdk环境,官方下载nexus和maven,解压后创建 ... -
ubuntu10.04下eclipse的安装及配置
2012-03-14 00:01 1307从官方http://www.eclipse.org/downl ... -
Ubuntu10.04下配置java环境变量
2012-03-13 23:28 1066Ubuntu10.04默认安装了OpenJDK,但还是基于Su ... -
eclipse设置保护色
2012-03-16 09:22 9414eclipse操作界面默认颜色为白色。对于我们长期使 ... -
OSGI学习笔记(六)
2012-03-17 15:08 2754SpringDM初步使用(一) 官方地址http:// ... -
OSGI学习笔记(八)
2012-03-19 21:08 2301SpringDM初步使用(三) spring第三个例子 ... -
OSGI学习笔记(五)
2011-07-31 10:32 1586开放服务网关协议 (Open Services Gateway ... -
osgi学习笔记(三)
2011-07-16 22:43 1960OSGI实战书上讲了一个web登陆验证切换功能。表达了osgi ... -
word工具类
2011-03-15 09:19 1443package org.foreverframework ... -
命令模式--撤销恢复
2011-03-14 22:32 4986该例子来自阎宏提供的 ... -
java zip
2011-03-06 15:32 1215import java.io.BufferedInputStr ... -
doc转swf
2010-12-07 22:03 8540将doc转换成swf,然后显示在html页面上。 packa ... -
javamail简单使用
2010-11-15 08:29 2350MailInfo类: //发送邮件的信息类 public ... -
xloadtree的一个改造
2010-09-20 22:58 2568修改了xloadtree的部分源码以适合自己使用。 1.修改 ... -
java与Delphi写的dll交互
2010-09-05 22:27 6161有时候在项目开发的时候难免会和硬件提供的开发包接触,这些开发接 ... -
JAVA与DLL交互
2010-08-27 23:32 1945jna官网地址:https://jna.dev.java.ne ... -
office工具类
2010-07-31 14:17 2309将jcom.dll放入jdk的bin目录下,将jcom.jar ... -
启动多个tomcat
2010-04-22 09:13 1215想启动多个tomcat,只需修改conf/server.xml ...
相关推荐
在实际开发中,DOM4J常用于读取XML配置文件、解析XML数据、生成XML报告等场景。例如,通过`Document`对象读取XML文件,然后使用`Element`和`XPath`来获取或修改数据。同时,DOM4J还提供了`Writer`接口,可以将XML...
1. 支持XPath:DOM4J提供了一种强大的方式来查询XML文档,通过XPath表达式可以轻松地找到需要的数据。 2. 文档对象模型:它允许开发者以面向对象的方式处理XML文档,包括元素、属性、文本节点等。 3. 轻量级:DOM4J...
例如,Spring框架就曾使用dom4j来解析和生成XML配置文件。此外,它也是许多Java XML库和框架的底层实现,如Hibernate的ORM映射文件处理。 总结来说,dom4j-1.6.1.jar是一个强大且全面的XML处理工具,为Java开发者...
8. **与Spring框架集成**:在Spring框架中,DOM4J常用于配置文件的解析,例如Spring的bean定义XML文件。 DOM4J的版本迭代带来了许多改进和新特性,例如从1.6.1到2.1.1的过程中,可能包含了性能优化、API调整、错误...
4. **事件驱动处理**:DOM4J支持SAX事件驱动的XML解析,可以在解析过程中触发自定义事件处理器,适合处理大型XML文件。 5. **文档操作**:DOM4J允许开发者创建新的XML文档,或者修改已有的文档。可以添加、删除、...
在实际开发中,DOM4J常用于XML配置文件的读写,如Spring框架的配置文件处理。此外,它还广泛应用于数据交换、XML数据的序列化与反序列化,以及XML文档的转换等场景。 五、API使用示例 以下是一个简单的示例,展示...
**DOM4J-1.6.1完整jar包** ...DOM4J负责XML的解析和操作,Jaxen提供了XPath支持,而Sitemesh则用于统一和管理Web应用的页面布局。这些工具的结合使用,能够帮助开发者更高效地处理XML数据并构建美观一致的Web应用。
《深入解析DOM4J-2.1.1.jar:Java XML处理的核心库》 DOM4J,全称为“Document Object Model for Java”,是Java平台上一个非常优秀的XML处理库。它是一个开源项目,提供了丰富的API来处理XML文档,包括读取、创建...
例如,可以通过dom4j解析XML配置文件,将其中的数据插入到Oracle数据库;反之,也可以从数据库中查询数据,然后用dom4j生成XML报告。这种组合使得数据交换和存储更加便捷,提高了代码的可维护性和灵活性。 总结,...
**DOM4J——XML解析库详解** XML(eXtensible Markup Language)作为一种标记语言,广泛应用于数据交换、配置文件和文档存储等领域。在Java环境中,解析XML文档时,我们通常会遇到各种库,其中DOM4J是一个非常流行...
- **SAX支持**:除了DOM模型,DOM4J还支持SAX解析,适用于处理大型XML文件。 - **JAXB集成**:与Java对象绑定框架JAXB有良好的集成,方便XML与Java对象间的转换。 3. **使用DOM4J解析XML** - 创建XML文档:可以...
1. **读取XML**: dom4j提供了`DocumentReader`和`SAXReader`类,分别基于DOM和SAX解析XML文件。 2. **写入XML**: `DocumentWriter`和`XMLWriter`类用于将构建的XML对象序列化为XML字符串或文件。 3. **修改XML**: ...
在配置文件管理中,开发者可能使用DOM4J读取XML配置,然后通过Jaxen动态修改配置参数,以适应不同的运行环境。 总的来说,DOM4J-1.6.1.jar和Jaxen-1.1-beta-6.jar是Java XML编程的重要工具,它们为处理XML文档提供...
4. **事件驱动模型**:对于大型XML文件,DOM4J支持SAX解析器的事件驱动模式,避免一次性加载整个文档到内存。 5. **文档构建**:DOM4J不仅能够解析XML,还能方便地创建新的XML文档或者修改现有文档。 6. **XML ...
2. **SAX和DOM**: 除了DOM,DOM4J还支持SAX解析器,允许在内存有限的情况下处理大型XML文件。 3. **XPath**: 支持XPath表达式,使得可以方便地定位和提取XML文档中的特定节点。 4. **事件模型**: 提供了基于事件的...
7. **Spring框架集成**:DOM4J与Spring框架有紧密的联系,Spring使用DOM4J来解析和构建配置文件,如XML形式的bean定义。 8. **许可证信息**:压缩包中的"springframework-license.txt"可能包含了Spring框架相关的...
标题中的"dom4j-2.1.1.zip"是指DOM4J库的2.1.1版本的压缩包,包含了一个名为"dom4j-2.1.1.jar"的核心库文件,这是开发者在项目中引入DOM4J时所需要的主要依赖。 XML(eXtensible Markup Language)是一种用于标记...
DOM4J可以加载和解析XML文档,然后利用XPath表达式进行数据检索。这种方式避免了传统遍历DOM树的低效,尤其是在大型XML文档中,XPath的查询性能优势尤为明显。 在Java项目中,通常会将DOM4J和XPath的jar包打包在...