首页> 中国专利> 实现Java与XML数据绑定的方法

实现Java与XML数据绑定的方法

摘要

本发明揭示了一种实现Java与XML数据绑定的方法,包括以下步骤:1)设计XML文档;2)根据XML文档的结构来创建与元素相对应的Java类;3)设置XML元素与Java类的对应关系;4)实现解组算法,采用递归算法实现对XML文档树的遍历,创建与整个XML文档结构相对应的Java对象;5)实现编组算法,采用递归算法实现对Java对象树的遍历,创建与整个Java对象树结构相对应的XML文档;6)实现解组和编组类,本发明实现java对象与XML文档之间双向的数据映射绑定,简化使用XML的开发工作,实现了解析XML文档到创建java对象的自动化过程,能将修改后的java对象回写到XML文档中,并能够通过少量的Java代码修改来便捷的适应XML文档结构的变化。

著录项

  • 公开/公告号CN101699397A

    专利类型发明专利

  • 公开/公告日2010-04-28

    原文格式PDF

  • 申请/专利权人 上海宝信软件股份有限公司;

    申请/专利号CN200910196923.8

  • 发明设计人 许正超;

    申请日2009-10-09

  • 分类号G06F9/44;G06F17/30;

  • 代理机构上海金盛协力知识产权代理有限公司;

  • 代理人季江胜

  • 地址 201203 上海市浦东张江高科技园区郭守敬路515号

  • 入库时间 2023-12-17 23:40:01

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2015-09-16

    授权

    授权

  • 2012-08-08

    实质审查的生效 IPC(主分类):G06F9/44 申请日:20091009

    实质审查的生效

  • 2010-04-28

    公开

    公开

  • 2010-03-10

    地址不明的通知 收件人:胡云 文件名称:发明专利申请初步审查合格通知书 申请日:20091009

    地址不明的通知

说明书

技术领域

本发明涉及政府及企业管理软件领域,特别涉及一种实现Java与XML数据绑定的方法。

背景技术

XML(Extensible Markup Language)即可扩展标记语言,是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,由于XML简单易于掌握和使用,使得XML广泛应用于各种应用软件中,成为目前软件开发配置的重要组成部分和数据交换的公共语言。在Java中处理XML的基础API是DOM,SAX,JDOM,dom4j等,这些API为Java处理XML提供了解决方案,但是不足的是使用方法复杂,在使用的过程中容易发生错误。

Java与XML数据绑定是一种建立在基础API之上的更高级的XML处理机制,它提供了一种简单而直接的方法在Java平台应用程序中使用XML,实现了将XML文档数据绑定到Java对象,或者是将Java对象数据绑定到XML文档,应用程序可以在很大程度上忽略XML文档的实际结构,而直接使用那些文档的数据内容,对于那些关心XML数据内容,而不关注XML文档结构细节的应用程序,比如用于数据交换和具有固定结构的配置文件,比较适合采用Java与XML数据绑定技术来读写XML。

目前常见的技术有JAXB、XStream、JiBX等。

1、JAXB

JAXB(Java Architecture for XML Binding,Java XML绑定架构)是一个处于不断发展中的Java平台数据绑定标准,该技术可以提供将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。另外,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便加载XML数据,并以XML文件作为数据存储方式。

2、XStream

XStream采用xpp来进行XML和对象之间的转换,它不需要schema或其他的mapping文件就可以进行java对象和XML文件之间的转换,API调用起来非常方便,并且扩展功能强大。在生成的XML中对象名变成了元素名,类中的字符串组成了XML中的元素内容。使用XStream序列化的类不需要实现Serializable接口。XStream可以说是一种序列化工具而不是数据绑定工具。和其他序列化工具相比,XStream有三个突出的特点:

XStream不关心序列化/逆序列化的类的字段的可见性。

序列化/逆序列化类的字段不需要getter和setter方法。

序列化/逆序列化的类不需要有默认构造函数。

不需要修改类,使用XStream就能直接序列化/逆序列化任何第三方类。

3、JiBX

JiBX是一个绑定XML数据到Java对象的框架。JiBX用一个绑定定义文挡(bindingdefinition document)来定义XML数据与Java对象转换的规则,使用JiBX的过程分成两个过程,一个是binding compiler,另一个是binding runtime。binding compiler是一个前期准备过程,包括定义绑定定义文挡,定义与XML绑定在一起的Java对象,然后编译。JiBX使用字节代码增强而不是反射来在项目构建时将挂钩添加进应用程序代码JiBX不是根据DTD或Schema生成代码,而是使用绑定定义,该定义将用户提供的类与XML结构相关联。优点在于它是一种针对性能而设计的数据绑定框架,缺点是需要对POJO进行增强,每次重新编译后都必须重新进行增强。

JAXB和JiBX根据XML Schema生成Java代码和相应配置文件,这是处理Java与XML数据绑定的一种代码生成方式。另一种主要方式是使用某种形式的映射绑定方法,在映射绑定方法中,构建自己的类(或者最初根据schema来构建Java类,然后修改它们以满足您的要求),并向绑定框架指定这些类如何与XML文档相关联。XStream和本方法则采用第二种方式。

表:特性比较

  JAXB  XStream  JiBX  本方法 技术实现方式  代码生成  映射绑定  映射绑定+  字节码增强  映射绑定 XML文档格式和Java应 用程序隔离度  低  高  中  高 根据XML语法生成代码  是  否  否  否 支持的功能  中  中  多  少 灵活性  低  高  高  高  实用性  高  高  中  高  性能表现  中  中  高  中  学习难度  高  中  高  低

采用代码生成方式的JAXB和JiBX的主要缺点如下:

1)通过如此贴实地反映文档结构,使应用程序代码和文档结构之间紧密耦合。

2)如果XML文档结构发生变化,再需要重新生成代码,并修改应用程序代码以使用最终修改后的数据类。

映射绑定方式比代码生成具有更大的灵活性。使用真正的对象类将数据和行为组合在一起。也可以在一定程度上解除对象类与实际XML之间的耦合。修改映射定义(而不需要改变应用程序代码)通常处理XML文档结构中微小的变化。甚至可以用一种格式定义单独的输入和输出映射来对文档进行数据分解,并用另一种格式编组它们。

为了解决上述问题,中国专利公开号:CN101339500,揭示了一种基于XML模式的数据绑定应用程序接口生成方法针对实际中存在的复杂XMLschema规范,提出了一种自动生成用于操作符合XMLSchema规范的XML文件的数据绑定API的方法。其特征为该方法以数据绑定技术为基础,首先生成一套与生成目标语言类型无关的中问层,然后通过独立的代码生成引擎生成所需类型目标代码。本文基于新华社颁布的CNMLSchema(中文新闻置标语言)以及CNML稿件模板进行代码生成和测试,实验证明,这种方法在保证API的健壮性和正确性的基础上,同时具有了极大的灵活性,可以大幅降低schema规范变迁所带来的API维护成本,保持多种语言API接口的基本一致性以降低培训成本,同时也为基于API之上的应用系统提供稳定的支持。但在实际使用中,Java的使用范围更高,本发明没有提供针对Java的数据绑定方法。

有鉴于此,本领域发明人研发了一种实现Java与XML数据绑定的方法。

发明内容

本发明的目的在于,提供一种实现Java与XML数据绑定的方法,克服了现有技术的困难,已达到实现java对象与XML文档之间双向的数据映射绑定,简化使用XML的开发工作,实现了解析XML文档到创建java对象的自动化过程,能将修改后的java对象回写到XML文档中的目的,并能够通过少量的Java代码修改来便捷的适应XML文档结构的变化。

本发明采用如下技术方案:

本发明的一种实现Java与XML数据绑定的方法,包括以下步骤:

1)设计XML文档;

2)根据XML文档的结构来创建与元素相对应的Java类;

3)设置XML元素与Java类的对应关系;

4)实现解组算法,采用递归算法实现对XML文档树的遍历,创建与整个XML文档结构相对应的Java对象;

5)实现编组算法,采用递归算法实现对Java对象树的遍历,创建与整个Java对象树结构相对应的XML文档;

6)实现解组和编组类。

进一步地,所述步骤2)中,所述XML元素类型包括简单类型和复杂类型,所述简单类型的值不包含子元素或属性,复杂类型是可以包含其他子元素或属性的用户定义的数据类型,复杂类型可以包含定义为简单类型或复杂类型的元素。

进一步地,所述步骤2)中,所述XML文档中的每个复杂类型都有一个Java类与之相对应。

进一步地,所述步骤2)中,复杂类型元素里的属性和简单类型子元素与Java类的属性相对应。

进一步地,所述步骤3)中,通过一个节点类型和Java类的对应表来存放这种对应关系,所述对应表的键为XML文档元素名称,值为Java类的完整路径。

进一步地,所述步骤4)中,采用基础XMLAPI将XML文档读入到输入流中,创建成为XML文档对象,然后取得文档的根元素传入实现递归算法的解组方法,在递归过程中取得XML文档元素与Java类的对应关系,采用Java反射机制创建Java对象。

进一步地,所述步骤4)包括以下步骤:

401)将XML文档读入到输入流中,创建成为XML文档,并取得根元素;

402)将XML文档元素传入解组方法;

403)取得与当前元素相对应的Java类,配置存放在元素与Java类对应表中;

404)使用Java反射机制,创建与当前元素对应的Java对象实例;

405)取得当前元素的所有属性,循环读取属性,使用Java反射机制调用setXxx方法,将属性值作为参数传入;

406)取得当前元素的所有子元素;

407)判断是否有子元素,若有,执行步骤408),若没有,执行步骤410);

408)对所有子元素进行循环读取;

409)使用Java反射机制,调用Java类的getXxxList()方法取得当前Java对象中针对当前子元素的List容器,将递归调用方法自身得到的对象加入到这个List容器中,执行步骤402);

410)返回当前对象实例;

411)解组方法最后返回的对象即为与整个XML文档相对应的Java对象实例。

进一步地,所述步骤5)中,将Java对象传入实现递归算法的编组方法中,在递归过程中取得XML文档元素与Java类的对应关系,采用XML基础API创建XML文档。

进一步地,所述步骤5)中,包括以下步骤:

501)取得Java根对象;

502)将Java对象传入到编组方法;

503)使用Java反射机制,取得当前对象的类路径;

504)从元素与Java类对应表中取得与当前对象类路径对应的XML元素名称,并以该名称创建元素;

505)使用Java反射机制,取得当前对象的所有属性,对所有属性进行循环读取,若属性名称不具有List和Map结尾,则将属性名称转换成规范的XML属性名称后,添加到XML当前元素的属性中;

506)若属性名称具有List结尾,则将其添加到子元素列表中;

507)判断是否存在子对象,若是,执行步骤508),若否,执行步骤510);

508)对子元素列表进行循环读取,获得每一个子元素;然后再取得子元素列表中的所有子对象,将子对象设为当前对象;

509)调用编组方法得到返回元素,将返回元素添加为当前元素的子元素,执行步骤502);

510)返回当前元素;

511)编组方法最终返回的元素即为与Java对象对应的XML元素。

进一步地,所述步骤6)中,在解组类中,使用XML基础API从输入流中读取XML文档,然后调用解组方法读取XML文档映射为Java对象树;在编组类中,调用编组方法读取Java对象树映射为XML文档,并可使用XML基础API将XML文档输出到输出流中。

本方法主要采用递归算法遍历XML文档和Java对象树,通过Java反射机制和XML处理基础API来实现Java与XML的数据绑定,使得Java开发者不需要了解太多的XML知识即可实现对XML的处理,简化了使用XML的开发工作,降低了开发难度,提高了开发效率。

Java反射机制是在运行时访问有关Java语言类的信息的一种方法,可用它来访问类实例中的字段和方法,从而提供了一种在运行时将类动态地挂钩在一起,却无需类之间有任何源代码链接的方法。反射是一种功能非常强大的Java技术特性,但是将其与调用方法或直接访问已编译代码中的字段相比,它在性能上有些欠缺。

由于采用了以上技术,本发明与现有技术相比,通过Java与XML数据绑定,Java开发者可以将XML文档映射为Java对象,通过对象访问数据,这样能更容易看清楚真正的数据,也更很容易访问这些数据。由于映射生成的Java存在于内存中,不需要遍历文档结构以获取数据,因此可以获得更好的访问速度。在输入时,一些特殊类型的数据(比如数字和日期)可以被转换成内部表示,而不是保留为文本形式;这使应用程序可以更有效地使用数据值。当XML文档结构发生调整时,只要修改相应映射的Java类就可以满足读写的需要,而不需要修改XML解析程序,非常便捷。若XML的元素增减属性或子元素,也只需要在映射的Java类中做修改即可。

本Java与XML数据绑定的方法在数据交换与软件配置文件中将具有良好的应用前景,使得Java开发者在应用程序中能方便加载和使用XML数据,并以XML文件作为数据存储方式。

附图说明

图1为本发明实施例的Java与XML数据绑定示例-客户信息的信息交换图表;

图2为本发明的Java与XML数据绑定方法的流程图;

图3为本发明方法的步骤4)中解组算法的流程图;

图4为本发明方法的步骤5)中递归算法的流程图。

具体实施方式

下面通过图1至4,来介绍本发明的一种具体实施例。

如图2至4所示,本发明的一种实现Java与XML数据绑定的方法,包括以下步骤:

步骤一:设计符合规范的XML文档,采用本方法实现数据绑定的XML需要符合XML设计规范。

步骤二:根据XML文档的结构来创建与元素相对应的Java类。

XML元素类型包括简单类型和复杂类型,简单类型的值不能包含元素或属性,复杂类型可以产生在其他元素中嵌套元素的效果,或者为元素增加属性。

XML文档中的每个复杂类型的元素都应该有一个Java类与之相对应,元素里的属性和简单类型的子元素与Java类的属性相对应,这些属性应设计为Java基本类型包装类型(比如Integer)、String以及这些类型的数组类型(比如Integer[]或String[])的xxx;如果有复杂类型的子元素,则设计为List类型的xxxList和Map类型的xxxMap。最后,为这些属性提供getXxx()和setXxx()方法。

客户信息对应到两个Java类:Customer和Address,增加childFields的属性定义,指明需要按子元素的方式显示的那些属性。

步骤三:设置XML元素与Java类的对应关系。可以通过一个节点类型和Java类的对应表来存放这种对应关系。键为XML文档元素名称,值为Java类的完整路径,

步骤四:实现解组算法,采用递归算法实现对XML文档树的遍历,创建与整个XML文档结构相对应的Java对象。采用基础XML API将XML文档读入到输入流中,创建成为XML文档对象,然后取得文档的根元素传入实现递归算法的解组方法,在递归过程中取得XML文档元素与Java类的对应关系,采用Java反射机制创建Java对象。

参见图3,所述步骤4)包括以下步骤:

401)将XML文档读入到输入流中,创建成为XML文档,并取得根元素;

402)将XML文档元素传入解组方法;

403)取得与当前元素相对应的Java类,配置存放在元素与Java类对应表中;

404)使用Java反射机制,创建与当前元素对应的Java对象实例;

405)取得当前元素的所有属性,循环读取属性,使用Java反射机制调用setXxx方法,将属性值作为参数传入;

406)取得当前元素的所有子元素;

407)判断是否有子元素,若有,执行步骤408),若没有,表明已经到叶子元素,执行步骤410);

408)对所有子元素进行循环读取;

409)使用Java反射机制,调用Java类的getXxxList()方法取得当前Java对象中针对当前子元素的List容器,将递归调用方法自身得到的对象加入到这个List容器中,执行步骤402);

410)返回当前对象实例;

411)解组方法最后返回的对象即为与整个XML文档相对应的Java对象实例。

步骤五:实现编组算法,采用递归算法实现对Java对象树的遍历,创建与整个Java对象树结构相对应的XML文档。将Java对象传入实现递归算法的编组方法中,在递归过程中取得XML文档元素与Java类的对应关系,采用XML基础API创建XML文档。这样就实现了Java对象与XML文档之间双向的数据绑定。

参见图4,所述步骤5)包括以下步骤:

501)取得Java根对象;

502)将Java对象传入到编组方法;

503)使用Java反射机制,取得当前对象的类路径;

504)从元素与Java类对应表中取得与当前对象类路径对应的XML元素名称,并以该名称创建元素;

505)使用Java反射机制,取得当前对象的所有属性,对所有属性进行循环读取,若属性名称不具有List和Map结尾,则将属性名称转换成规范的XML属性名称后,添加到XML当前元素的属性中;

506)若属性名称具有List结尾,则将其添加到子元素列表中;

507)判断是否存在子对象,本实施例中通过判断子元素列表的长度,若长度为0,表明当前对象没有子对象,若长度大于0,执行步骤510);若子元素列表的长度大于0,执行步骤508);

508)对子元素列表进行循环读取,获得每一个子元素;然后再取得子元素列表中的所有子对象,将子对象设为当前对象;

509)调用编组方法得到返回元素,将返回元素添加为当前元素的子元素,执行步骤502);

510)返回当前元素;

511)编组方法最终返回的元素即为与Java对象对应的XML元素。

步骤六:实现解组和编组类。在解组类中,使用XML基础API从输入流中读取XML文档,然后调用解组方法读取XML文档映射为Java对象树。在编组类中,调用编组方法读取Java对象树映射为XML文档,并可使用XML基础API将XML文档输出到输出流中。

参见图1,对上述技术方案进行测试,步骤如下:

1)读取″d:/customer.xml″到输入流,″d:/customer.xml″文件为“清单一”的XML文档;

比如以下的例子:

清单一:客户信息<?xml version=″1.0″encoding=″UTF-8″?><customer id=″1″>  <name>张三</name>   <age>20</age>   <pet-name>汪汪</pet-name>   <address id=″1″>         <street>南京西路200号</street>          <city>上海</city>          <zip>123456</zip>   </address>   <address id=″2″>         <street>天钥桥路300号</street>          <city>上海</city>          <zip>654321</zip>   </address></customer>

2)通过解组类UnmarshallingContext将XML文档其映射到Customer对象;

3)读取Customer的属性和子对象Address列表并输出到控制台;

4)修改客户Customer的姓名和地址Addess的邮编属性;

5)通过编组类MarshallingContext将Customer对象映射到XML文档;

6)输出到″d:/test.xml″。

代码如下:

清单二:测试代码

public class EasyjxbTest{    /**      *@param args      */    public static void main(String[]args){        //创建xml节点的java类型        Map nodeClassMap=new HashMap();        nodeClassMap                .put(″customer″,    ″com.baosight.workflow.application.configuration.element.Customer″);

        nodeClassMap                .put(″address″,   ″com.baosight.workflow.application.configuration.element.Address″);        Customer customer=null;        //将XML文档映射到Java对象树        UnmarshallingContext unmarshallingContext=new UnmarshallingContext(nodeClassMap);        try{             InputStream inputStream=new FileInputStream(new File(                      ″d:/customer.xml″));             customer=(Customer)unmarshallingContext                     .unmarshalDocument(inputStream);        }catch(FileNotFoundException e1){            e1.printStackTrace();        }        System.out.printIn(″客户ID:″+customer.getId());        System.out.printIn(″客户姓名:″+customer.getName());        System.out.printIn(″客户年龄:″+customer.getAge());        System.out.printIn(″客户的宠物名:″+customer.getPetName());        System.out.printIn(″====================″);        //修改客户姓名        customer.setName(″李四″);        List addressList=customer.getAddressList();        for(int i=0;i<addressList.size();i++){             Address address=(Address)addressList.get(i);             System.out.printIn(″地址ID:″+address.getId());             System.out.printIn(″街道:″+address.getStreet());             System.out.printIn(″城市:″+address.getCity());             System.out.printIn(″邮编:″+address.getZip());             System.out.printIn(″====================″);             //修改地址邮编             address.setZip(″000000″);        }        //将Java对象树映射到XML文档        MarshallingContext marshallingContext=new MarshallingContext(                 nodeClassMap);        try{

           marshallingContext.marshalJavaObject(customer);           marshallingContext.saveXML(new File(″d:/test.xml″));      }catch(Exception e){          e.printStackTrace();      }   }}

输出结果如下:

清单三:测试控制台上的输出

  客户ID:1  客户姓名:张三  客户年龄:20  客户的宠物名:汪汪  ====================  地址ID:1  街道:南京西路200号  城市:上海  邮编:123456  ====================  地址ID:2  街道:天钥桥路300号  城市:上海  邮编:654321  ====================

清单四:输出的″d:/test.xml″文件内容

  <?xml version=″1.0″encoding=″UTF-8″?>-<customer id=″1″>  <name>李四</name>  <age>20</age>  <pet-name>汪汪</pet-name>-<address id=″1″>  <street>南京西路200号</street>  <city>上海</city>  <zip>000000</zip>  </address>-<address id=″2″>  <street>天钥桥路300号</street>  <city>上海</city>  <zip>000000</zip>  </address>  </customer>

对结果进行检查,“清单三”中的客户的信息与“清单一”相比较是一致的,“清单四”的XML文档是经过修改后的信息,且与“清单一”的结构相同,因此可以表明本方法能够达到Java与XML数据绑定的效果。

本方法采用了递归算法对树进行遍历,也可以修改为采用栈存储的非递归算法进行遍历,非递归算法在XML的层次结构较多的情况下会起到一定的优化效果。

本方法的技术方案主要应用了Java XML基础API解析XML文档,也可以使用其他的XML解析技术,如DOM、SAX、DOM4J等。

此外,本方法中的Java类是手工书写的,可以通过一些代码生成工具从XML Schema生成相应的Java类。

在水利部太湖流域管理局电子政务系统中,工作流管理的配置文件即采用本方法实现。

综上可知,本发明通过Java与XML数据绑定,Java开发者可以将XML文档映射为Java对象,通过对象访问数据,这样能更容易看清楚真正的数据,也更很容易访问这些数据。由于映射生成的Java存在于内存中,不需要遍历文档结构以获取数据,因此可以获得更好的访问速度。在输入时,一些特殊类型的数据(比如数字和日期)可以被转换成内部表示,而不是保留为文本形式;这使应用程序可以更有效地使用数据值。当XML文档结构发生调整时,只要修改相应映射的Java类就可以满足读写的需要,而不需要修改XML解析程序,非常便捷。若XML的元素增减属性或子元素,也只需要在映射的Java类中做修改即可。

本Java与XML数据绑定的方法在数据交换与软件配置文件中将具有良好的应用前景,使得Java开发者在应用程序中能方便加载和使用XML数据,并以XML文件作为数据存储方式。

以上所述的实施例仅用于说明本发明的技术思想及特点,其目的在于使本领域内的技术人员能够了解本发明的内容并据以实施,不能仅以本实施例来限定本发明的专利范围,即凡依本发明所揭示的精神所作的同等变化或修饰,仍落在本发明的专利范围内。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号