java进行xml与实体类互转

XStream与Jsoup解析xml的工具.这里总结一下.

1:相关依赖:
<!--xstream相关依赖-->
<dependency>
	<groupId>com.thoughtworks.xstream</groupId>
	<artifactId>xstream</artifactId>
    <version>1.4.9</version>
</dependency>
<!--Jsoup相关依赖-->
<dependency>
	<groupId>org.jsoup</groupId>
	<artifactId>jsoup</artifactId>
	<version>1.10.3</version>
</dependency>
2:针对XStream与Jsoup进行封装
package com.itmck.util;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import org.jsoup.parser.XmlTreeBuilder;

import com.itmck.pojo.MS;
import com.itmck.pojo.QueryMsg;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * 
 * @ClassName: XMLUtil
 * @Description: TODO(XML字符串与实体类之间互转) 需要依赖xsream Jsoup 注意依赖版本问题
 * @author 34745
 * @date 2019年1月31日
 *
 */
public class XMLUtils {

	/**
	 * 
	 * @param clazz
	 *            类的字节码文件
	 * @param xml
	 *            传入的XML字符串
	 * @return XML字符串转实体类
	 */
	public static <T> T parseFromXml(Class<T> clazz, String xml) {
		XStream xStream = new XStream(new DomDriver());
		xStream.processAnnotations(clazz);
		@SuppressWarnings("unchecked")
		T t = (T) xStream.fromXML(xml);
		return t;
	}

	/**
	 * 
	 * 
	 * @param obj
	 *            实体类
	 * @return 实体类转XML字符串
	 */
	public static String toXml(Object obj) {
		XStream xStream = new XStream(new DomDriver());
		// 扫描@XStream注解
		xStream.processAnnotations(obj.getClass());
		return xStream.toXML(obj).replaceAll("\\_+", "_");//正则过滤双下划线转为单下划线
	}

	/**
	 * 
	 * @Description: 获取xml格式字符串中指定的元素标签片段
	 * @param xml
	 *            需要xml格式的字符串
	 * @param elementId
	 *            节点名
	 * @return
	 */
	public static String getElementString(String xml, String elementId) {
		if (StringUtils.isBlank(xml) || StringUtils.isBlank(elementId)) {
			return null;
		}
		// 获取document对象
		Document document = Jsoup.parse(xml, "", new Parser(new XmlTreeBuilder()));
		// 获取对应的document片段
		return document.select(elementId).toString().replaceAll("\\s*", "");
	}

	/**
	 * 
	 * @Description: xml字符串节点片段转对象
	 * @param xml
	 * @param elementId
	 * @param clazz
	 * @return
	 */
	public static <T> T parseElementObj(String xml, String elementId, Class<T> clazz) {
		if (StringUtils.isBlank(xml) || StringUtils.isBlank(elementId)) {
			return null;
		}
		return parseFromXml(clazz, getElementString(xml, elementId));
	}
}
3封装实体类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@XStreamAlias("QUERYMSG")
public class QueryMsg {

	@XStreamAlias("HEAD")
	private Head head;
	@XStreamAlias("CONTENT")
	private Content content;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
@XStreamAlias("HEAD")
public class Head{

	private String SEQ;
	private String NAME;
}

@Data
@NoArgsConstructor
@AllArgsConstructor
@XStreamAlias("CONTENT")
public class Content {

	@XStreamAlias("FLG")
	private String F_LG;
	@XStreamAlias("MSG")
	private int M_SG;
}
测试代码如下:

public static void main(String[] args) {
		
		Content content = new Content();
		content.setF_LG("1");
		content.setM_SG(35);
		
		QueryMsg queryMsg = new QueryMsg(new Head("",""),content);
		
		String xml = XMLUtils.toXml(queryMsg);
		
		System.out.println(xml);
		
		QueryMsg parseFromXml = XMLUtils.parseFromXml(QueryMsg.class, xml);
		System.out.println(parseFromXml);
 
	} 

运行结果:

<QUERYMSG>
  <HEAD>
    <SEQ></SEQ>
    <NAME></NAME>
  </HEAD>
  <CONTENT>
    <FLG>1</FLG>
    <MSG>35</MSG>
  </CONTENT>
</QUERYMSG>
QueryMsg(head=Head(SEQ=, NAME=), content=Content(F_LG=1, M_SG=35))

说明: 一般这种需要俩注解就行了:
@XStreamAlias(“别名”) 配置别名
@XStreamImplicit//省略集合根节点
有些时候,xml数据同级含有多个.如下:

<student>
    <name>xStream</name>
    <age>10</age>
    <teacher>
        <name>chen</name>
        <age>10</age>
    </teacher>
    <books>
        <book>
            <bookName>海贼王</bookName>
            <price>20.4</price>
        </book>
        <book>
            <bookName>风雨</bookName>
            <price>30.5</price>
        </book>
    </books>
</student>

这就需要如下封装:

@XStreamAlias("student")
public class Student {

	private String name;
	private int  age;
	@XStreamAlias("teacher")//给节点起别名.可在此处.其实在对应类上使用即可
	private Teacher teacher;
	@XStreamAlias("books")//此处给books节点起别名.这种最好在类上给相应的Book类起别名
	private List<Book> books;
}

@XStreamAlias("teacher")
public class Teacher {

	private String  name;
	private int  age;
}

@XStreamAlias("book")
public class Book {

	private String bookName;
	private  Double price;
}

如果想要的是下面这种,就需要省略对应根节点 @XStreamImplicit

<student>
    <name>xStream</name>
    <age>10</age>
    <teacher>
        <name>chen</name>
        <age>10</age>
    </teacher>
     <book>
        <bookName>海贼王</bookName>
        <price>20.4</price>
     </book>
     <book>
         <bookName>风雨</bookName>
        <price>30.5</price>
   </book>
</student>

对应的Student类封装如下,其余不变

@XStreamAlias("student")
public class Student {

	private String name;
	private int  age;
	@XStreamAlias("teacher")//给节点起别名.默认xml节点为属性名
	private Teacher teacher;
	@XStreamImplicit
	private List<Book> books;
}

如果一个类嵌套很多子类,这样只需要在其父类上使用别名,其余子类不用使用,默认子类以对应的在父类中的属性名为xml节点.否则就是生成类的全路径作为xml节点

1:在上述的封装中我使用了Jsoup.目的是为了获取xml中的某个节点.其中使用了正则除去空格,以及缩进等字符.
2:另外注意的是:在使用XStream的时候如果属性使用的是"_"拼接的.如:
private String stu_name; 在生成xml的时候会默然两个下划线<stu__name></stu__name>
这里我也是用了正则转为一个下划线
3:上面实体类使用了lombok注解,为了免于生成getter与setter

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值