栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

手把手教你通过java解析xml

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

手把手教你通过java解析xml

手把手教你解析XML

期望通过每一次分享,让技术的门槛变低,落地更容易。 —— 周围

本文适用范围
  • 实际工作中遇到关于解析和转换xml的问题
  • 不懂,想详细了解学习如何解析xml的同学
本文目的

通过本文,你将解决如下问题:

  • xml数据结构对应的java实体结构是如何绑定的
  • 如何将xml结构数据转换成对象
  • 如何将对象转换为xml
原始数据

    
        E37AA69997D0F399E040007F0100484D
        20130809103931E37AA70270E78822E040007F01004851@gd.zg
        FR20130809103441000000001054@90001113@gd.zg
        40001009@jm.gd.cp
        中共江门市委办秘书科
        1
        RC01
        2013-08-09 10:39:32
        2013-08-09 10:35:21
        201308071@jm.gd.cp
        江门市委办法规文件报备系统
        
            
                
                
            
        
        
            
                E201310290563707@20000007@jm.gd.cp-print
                
                    21800168@jm.gd.cp
                    测试用户2
                    2013-10-30 9:19:55
                     
                    
                
            
        
    



上述的xml格式基本涵盖了标签值、标签属性值、集合等内容,我们了解了针对特殊数据格式的处理,解析起来就没问题了,下面所讲的xml例子全部来源于上面的xml原始数据。

前置环境

你需要导入xstream.jar的包

需要注意的细节
  • xml标签区分大小写,映射的时候不要认为它能够像sql一样,不管大小写
  • xml标签对应实体属性,应确保数据类型是一致的,不然拿不到数据或者报错
解释格式

下面将对常见的xml和后端java-model做一个对应格式映射

属性格式
E37AA69997D0F399E040007F0100484D
20130809103931E37AA70270E78822E040007F01004851@gd.zg

上述这种xml标签是节点标签名称如 ,并且内容数据是String类型, 对应到java实体就是下面的声明:

private String id;

private String guid;
对象格式

    21800168@jm.gd.cp
    测试用户2
    2013-10-30 9:19:55

如上述的格式,它对应的就是标签是一个对象,它下面包含了3个子节点。我们要将它们转换应该就是对象封装了,如下:

@XStreamAlias("prints")//标签名称是小写的prints,但是java对象声明是首字母大写不一致
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class Prints {

	
	private String operuri;

	
	private String opername;

	
	//此处的注解也是别名替换,声明绑定xml标签时,使用operdate,而不是属性名operdate1
	@XStreamAlias("operdate")
	private String operdate1;
	
	... (省略后续字段 及相关get/set方法)
}

接着,可以自己在对象里构建一个main方法做测试:

public static void main(String[] args) {
	String xml= "21800168@jm.gd.cp测试用户22013-10-30 9:19:55";
	//com.leadal.csa.common.utils.XmlUtil
	Prints prints = (Prints) XmlUtil.Xml2Object(xml, Prints.class);
	System.out.println(prints);	
}

好了,完成了第一个转换测试,接下来要继续介绍另一种对象格式的解析。


按照之前的理解,创建这个标签应该叫,那我们构造对应对象就可以了,但是你会发现,它没有子节点,只有像html标签一样的标签属性值,同样也可以提取,不过要换一个方式,下面提供2种方法:

@XStreamAlias("site")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class Site {

	
	@XStreamAsAttribute
	private String type;
	
	
	@XStreamAsAttribute
	private String uri;
	
	... (省略后续字段 及相关get/set方法)

上述第一种方式就是在属性值上添加@XStreamAsAttribute注解,可以实现提取的type属性。

@XStreamAlias("site")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter.class)
public class Site {

	
	private String type;
	
	
	private String uri;
	
	... (省略后续字段 及相关get/set方法)

而第二种方式,属于全局设置,更改类上面@XStreamConverter注解中的转换器ToAttributedValueConverter.class,可完成提取的所有标签属性,直接绑定到对应的参数名称上。

集合格式

    
    

如上述所见的格式,中包含了2个,很明显里面声明的关于site内容应该是集合类型。

@XStreamAlias("status")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class SendDocStatus {

	
	@XStreamAsAttribute
	private String exchid;
	
	
	@XStreamImplicit //修饰site对应的标签是集合,会出现多个
	private List site;
	
	...(省略后续字段 及相关get/set方法)

如上述代码,@XStreamImplicit完成了对集合类型的修饰,如果不声明该注解,可以试试解析会报什么错,应该会提醒你标签重复了,因为程序不知道它是集合类型,无法接收到。

具体操作

首先我们得有一个概念:在java里,一切都是对象,xml数据也不例外。
那么,我们要针对xml标签名称去创建对应的实体对象

如下图,先创建一个实体对象,将xml的对象对应到了该对象上,要求是数据格式一致。(这里只抽取了 对象展示)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yXuVPQH9-1637921539708)(file:///C:/Users/Dell/Desktop/工作文档/blog/xml/xml1.png)]

结合前面的格式讲解,现在再根据这个图的指向,应该能清楚xml和java实体是如何对应的了。

关于如何调用API在java实体与xml数据之间转换,看下面的例子,使用的均是
com.leadal.csa.common.utils.XmlUtil

String xml= "21800168@jm.gd.cp测试用户22013-10-30 9:19:55";
//xml数据 转 java实体
Prints prints = (Prints) XmlUtil.Xml2Object(xml, Prints.class);
//java实体 转 xml数据
XmlUtil.Object2Xml(prints, prints.getClass());

常见异常错误 No such field xxx
com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: 
No such field com.leadal.csa.common.model.SendDocStatus.status

该错误是找不到对应的字段,如上述的错误案例,是找不到SendDocStatus.status下面的这个status属性。
通常这种错误,去检查字段属性名称是否拼错了,或者是否加了别名属性声明,导致最后无法与标签名称绑定上。

Duplicate field xxx
Exception in thread "main"
com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: 
Duplicate field print

这个错误,翻译过来是重复字段print,意思就是print这个属性重复出现了,但你的接收类型装不下多个,这种情况就要看自己是不是要根据xml结构,去把这个print变成集合。
我们看一下原始数据关于print的描述:

...

    ...
     
    

...

出现了2次这个标签,并且是以标签属性的方式设置值的,那么怎么设置类型才能将其成功封装到外部的标签中呢?如下:

@XStreamAlias("prints")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class Prints {

	@XStreamImplicit//此注解就是集合注解,参数名正好与标签名一致
	private List print;
	
	....(省略后续字段 及相关get/set方法)
}

@XStreamAlias("print")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter.class)
public class Print {

	
	private String num;

	....(省略后续字段 及相关get/set方法)
}

写在最后

以上就是关于如何解析xml的方式方法和将对象转成xml的方式,有问题可以再详细沟通,会使用到的注解我在下面统一列出并加上注释。

本文注解
//声明当前对象或属性名称的别名,必须与xml标签名一致,区分大小写
@XStreamAlias("prints")
//声明xml解析转换器,
//JavaClassConverter是普通java对象转换器
//ToAttributedValueConverter是适用于标签内属性值较多的转换器
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
//集合类型声明
@XStreamImplicit

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/602928.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号