在日常的工作中,我们经常需要处理xml格式的字符串,比如:调用第三方接口返回xml信息,需要解析xml获取相应的结果信息,之前自己写过一个利用 Java反射解析XML字符串,并封装到指定的JavaBean中的方法,最近的工作中又使用到了第三方接口,需要处理接口返回的XML字符串信息,对解 析XML的工具方法做了重新的优化,这里记录总结一下。

首先, 我们看下面xml格式的字符串:

//这里随便在网上搜索的xml字符串,简单做了修改

firstXmlStr = "<?xml  version=\"1.0\" encoding=\"GBK\"?>" +

"" +

"" +

"1001     " +

"Realfighter   " +

"81        " +

"1001号   " +

"" +

"";

假设现在我们需要获取到其中的结果信息,拿到用户的相关信息,并封装到指定的UserBean中,如下:

/**

* xml中需要的信息封装到User

* 这里继承BaseObject用于第二个解析xml的方法

* 注意:User的属性名必须与xml字符串中的标签一致

*/

class User extends BaseObject {

String users_id;//用户ID

String users_name;//用户名

String users_group;//用户分组

String users_address;//用户地址

public String getUsers_id() {

return users_id;

}

public void setUsers_id(String users_id) {

this.users_id = users_id;

}

public String getUsers_name() {

return users_name;

}

public void setUsers_name(String users_name) {

this.users_name = users_name;

}

public String getUsers_group() {

return users_group;

}

public void setUsers_group(String users_group) {

this.users_group = users_group;

}

public String getUsers_address() {

return users_address;

}

public void setUsers_address(String users_address) {

this.users_address = users_address;

}

@Override

public String toString() {

return "User{" +

"users_id=" + users_id +

", users_name='" + users_name + '\'' +

", users_group=" + users_group +

", users_address='" + users_address + '\'' +

'}';

}

}

我们通过以下方法解析xml并封装到指定对象,如下:

/**

* 封装xml信息到指定的Object

*

* @param returnXml

* @param obj

* @return Object

* @throws

* @Title: packReturnByXml

* @author Realfighter

*/

public static Object packReturnByXml(String returnXml, Object obj) {

Field[] fields = obj.getClass().getDeclaredFields();

for (Field field : fields) {

field.setAccessible(true);

String fieldname = field.getName();

try {

Pattern p = Pattern.compile(".*?"

+ fieldname + ">");

//匹配类似:1001     的字符

Matcher matcher = p.matcher(returnXml);

while (matcher.find()) {

Pattern p1 = Pattern.compile(">([^<>]*)

//匹配类似:>1001

Matcher m1 = p1.matcher(matcher.group(0).trim());

if (m1.find()) {

String value = m1.group(1).trim().equals("") ? null

: m1.group(1).trim();

Class> beanType = field.getType();

String setMethodName = "set"

+ fieldname.substring(0, 1).toUpperCase()

+ fieldname.substring(1);

Method m = obj.getClass().getMethod(setMethodName,

beanType);

m.invoke(obj, value);

}

}

} catch (Exception e) {

continue;

}

}

return obj;

}

测试如下:

@Test

public void testFirstXmlStr() {

User user = (User) packReturnByXml(firstXmlStr, new User());

System.out.println(user.toString());

//执行结果:

//User{users_id=1001, users_name='Realfighter', users_group=81, users_address='1001号'}

}

但是如果我们获取到的xml字符串是以下的类型,上面的方法就存在问题了,因为我们匹配到的不止是一条记录,我们需要的也是多个对象,如下:

secondXmlStr = "<?xml  version=\"1.0\" encoding=\"GBK\"?>" +

"" +

"" +

"1001     " +

"Realfighter   " +

"81        " +

"1001号   " +

"" +

"" +

"1002     " +

"Realfighter2   " +

"82        " +

"1002号   " +

"" +

"";

这时候,我们就需要改进一下上面的packReturnByXml方法,对其中匹配到的对象放入数组返回,如下:

/**

* 解析xml,封装成returnbean数组

*

* @param returnXml

* @param obj

* @return

* @throws IllegalArgumentException

* @throws IllegalAccessException

* @throws SecurityException

* @throws NoSuchMethodException

* @throws InvocationTargetException

*/

public static BaseObject[] packReturnArrayByXml(String returnXml, BaseObject obj)

throws IllegalArgumentException, IllegalAccessException,

SecurityException, NoSuchMethodException, InvocationTargetException {

Field[] fields = obj.getClass().getDeclaredFields();

List objs = new ArrayList();

int count = 0;//临时变量,用于计算可匹配到的对象数目

for (Field field : fields) {

field.setAccessible(true);

String fieldname = field.getName();

Pattern p = Pattern.compile(".*?"

+ fieldname + ">");

Matcher matcher = p.matcher(returnXml);

while (matcher.find()) {

//对象的复制方法

Object _obj = obj.clone();

objs.add(_obj);

count++;

}

if (count > 0) {

//一旦获取到对象数组,结束循环

break;

}

}

BaseObject[] objs2 = new BaseObject[count];

for (int i = 0; i

Object obj1 = objs.get(i);

for (Field field : fields) {

field.setAccessible(true);

String fieldname = field.getName();

try {

Pattern p = Pattern.compile(".*?"

+ fieldname + ">");

Matcher matcher = p.matcher(returnXml);

int num = 0;

while (matcher.find()) {

if (num == i) {

Pattern p1 = Pattern.compile(">([^<>]*)

Matcher m1 = p1.matcher(matcher.group(0).trim());

if (m1.find()) {

String value = m1.group(1).trim().equals("") ? null

: m1.group(1).trim();

Class> beanType = field.getType();

String setMethodName = "set"

+ fieldname.substring(0, 1)

.toUpperCase()

+ fieldname.substring(1);

Method m = obj1.getClass().getMethod(

setMethodName, beanType);

m.invoke(obj1, value);

}

}

num++;

}

} catch (NullPointerException e) {

continue;

}

}

objs2[i] = (BaseObject) obj1;

}

return objs2;

}

这里需要传入的是一个BaseObject对象,实现Cloneable接口的一个基类,实际的User对象需要继承此对象,以实现clone(),如下:

/**

* 基础的Object对象,实现Cloneable接口,用于调用clone()

*/

class BaseObject implements Cloneable {

@Override

public Object clone() {

Object obj = null;

try {

obj = super.clone();

} catch (CloneNotSupportedException e) {

e.printStackTrace();

}

return obj;

}

}

测试如下:

@Test

public void testSecondXmlStr() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {

BaseObject[] objs = packReturnArrayByXml(secondXmlStr, new User());

for (BaseObject base : objs) {

System.out.println(((User) base).toString());

}

//执行结果:

//User{users_id=1001, users_name='Realfighter', users_group=81, users_address='1001号'}

//User{users_id=1002, users_name='Realfighter2', users_group=82, users_address='1002号'}

}

总结:在XML信息比较简单的时候,不需要封装多个对象信息的时候,我们可以调用第一个方法:packReturnByXml解析xml封装到指定的对象 中,但是当xml信息比较复杂的时候,需要封装多个对象信息的时候,我们就需要将封装的对象继承BaseObject,通过调用 packReturnArrayByXml返回BaseObject数组,通过遍历数组拿到需要的相关信息。

java解析xml串标签_Java反射解析XML字符串并封装到指定的JavaBean相关推荐

  1. java xml格式验证_Java中对XML文件的校验

    Java中使用dtd校验xml文件: 1.定义一个校验类CheckXML类: import org.w3c.dom.Document; import org.xml.sax.EntityResolve ...

  2. java获取xml子节点_java如何获取XML中子节点的内容

    满意答案 wenwei0416 2013.03.28 采纳率:52%    等级:7 已帮助:408人 java中获取xml节点元素值 根据不同的处理xml方式不同而不同. java中解析xml的方式 ...

  3. java读取xml路径问题_java 中读取xml 和绝对路径

    一.得到绝对路径 本人用到的不多,就列举常用的. 以上2种可读取固定配置文件可用得到绝对路径 1.System.getProperty("user.dir"); 这个东西局限性十分 ...

  4. java xml 实体类_java中的xml与实体类之间的映射

    实体类: package xml; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class User ...

  5. java 解析xml 对象_Java反射——读取XML文件,创建对象

    读取XML文件,创建对象 config.xml import java.io.*; import java.lang.reflect.Constructor; import javax.xml.par ...

  6. java获取object属性值_java反射获取一个object属性值代码解析

    有些时候你明明知道这个object里面是什么,但是因为种种原因,你不能将它转化成一个对象,只是想单纯地提取出这个object里的一些东西,这个时候就需要用反射了. 假如你这个类是这样的: privat ...

  7. java反射 创建对象_Java反射――读取XML文件,创建对象

    config.xml <?xml version="1.0" encoding="UTF-8"?> import java.io.*; import ...

  8. java格式化时间到微秒_Java日期解析具有微秒或纳秒精度

    TL;博士 LocalDateTime.parse( // With resolution of nanoseconds, represent the idea of a date and time ...

  9. Java分析MySQL的数据结构_Java面试解析总结:Java+Redis+数据库+算法与数据结构+分布式...

    金九银十即将到来,给大家整理了今年来最经典的面试真题1000+道,每个题目都有详细的解答,收集了java基础.RabbitMQ,微服务.MySQL数据库.Java并发.JVM,Redis.设计模式,S ...

最新文章

  1. OpenGL在图形管道中调用了什么用户模式图形驱动程序(UMD)?
  2. codeforces数学1600day6[CodeForces - 1029C多区间交+枚举,CodeForces 992C[数学公式推导],CodeForces 992B[质因数分解+暴力枚举]]
  3. 算法 字符串转换为以为数组
  4. [转] 电子技术·笔记1(9月份)
  5. OpenFire、Spark、Smack介绍
  6. c# 变量,对象,静态类型,集合类的线程安全回顾
  7. JAVA——Windows双击jar包为可执行操作
  8. 支付宝服务窗接入常见问题说明
  9. JDK中没有jre文件夹和tools.jar文件
  10. V-3-3 在没有vCenter的情况下,复制虚拟机
  11. xshell连接linux出现乱码
  12. 查询手机号段对应地区编码_2020陕西专升本考试今日起查询成绩啦
  13. html新增伪类,css3新增伪类有哪些
  14. 海外并购频频被阻 中国芯发展之路困难重重
  15. 求相似三角形的几种方法,相似三角形 计算公式
  16. STM32单片机GPIO口简介
  17. 信息与安全工程学院2013-2014学年“五四”表彰获奖公示
  18. foxmail超大附件服务器文件怎么删,foxmail邮件太大怎么发?foxmail发送超大附件的方法...
  19. SDL_ttf库显示字体
  20. 《服务外包概论》知识点梳理

热门文章

  1. 2020山东省计算机专科学校排名,2021山东专科学校排名 最好的高职院校排行榜
  2. 计算机二级c选择题怎么准备,马上计算机二级考试,你准备得怎么样了?
  3. php 5.4 aws,亚马逊AWS.EC2:Ubuntu安装php与apache环境
  4. linux扩容后显示管理,linux之lvm管理及扩容
  5. 毛玻璃效果 php,CSS3如何实现磨砂玻璃背景效果
  6. ORACLE 11GR2 RAC new features 新特性。
  7. react-native viewpager用法
  8. android登陆的编写
  9. 基于JAVA+SpringMVC+Mybatis+MYSQL的理发预约系统
  10. 10个性鼠标指针主题包_游戏鼠标推荐