ITPub博客

首页 > > > 实现 Castor 数据绑定--转-5

实现 Castor 数据绑定--转-5

作者:longmanma 时间:2020-01-06 09:37:51 0 删除 编辑

指定 XML 元素的位置

但是,这里需要解决一个问题:书名和 ISBN 嵌套在book-info元素中,而不是直接嵌套在book元素中。所以需要在映射文件中指出这一情况。

当遇到这种情况时 — 一个类中的一个字段并不直接映射到与这个类对应的 XML 元素中的数据 — 就需要在bind-xml元素中使用location属性。这个属性的值应该是 XML 文档中包含您希望绑定到的数据的元素。如果绑定到元素数据,它就应该是目标元素的父元素;如果绑定到属性数据,它就应该是包含这个属性的元素。

因此,在这个示例中,希望把Book类的书名属性绑定到title元素的值,而这个元素嵌套在book-info元素中。下面是映射方法:

然后为书的 ISBN 添加另一个字段映射:

点击查看代码清单

现在,Book类的属性都已经设置好了。该处理Author类了。

 

回页首

对其他类进行映射

按照相同的方式对其他类进行映射。惟一的差异是在其他类中不需要使用map-to元素。

对 Author 类进行映射

需要把Author类中的字段映射到author元素。请记住,下面是要处理的 XML 片段:

<author>

<name first="Lincoln" last="Child" />

</author>

惟一需要注意的是,这里并不用两个元素分别包含名字和姓氏,而是使用一个带两个属性的元素。但是,前面已经使用过location属性(需要用这个属性指定name元素是映射到的位置)和node属性(可以在这里指定要绑定到属性数据,而不是元素)。所以在映射文件中需要以下代码:

点击查看代码清单

现在,您应该很容易看懂这些代码。这里指定了映射到的类(Author)和这个类上要映射的属性(FirstName和LastName)。对于每个属性,指定要查看的 XML 元素(都是name)并指定需要的是属性数据。

把 Book 和 Author 类链接起来

如果看一下上面的 XML,就会注意到并没有指定Author类应该映射到哪个 XML 元素。这是一个问题,因为 Castor 不会猜测您的意图;只要使用映射文件,最好指定所有映射信息。

如果每本书只有一位作者,那么在Book类中可能有一个Author属性。在这种情况下,可以在映射文件中插入以下代码:

<field name="Author" type="ibm.xml.castor.Author"><bind-xml name="author" /></field>

在这种情况下,把这一映射放在映射文件的图书部分中,因为映射的是属于Book类的一个属性。映射的类型指定为ibm.xml.castor.Author,并指定 XML 元素author。这样的话,Castor 的映射系统就会使用class元素中的Author类的定义处理作者的属性。

但是,问题在于Book类中没有 Author属性。相反,这个类中有一个Authors属性,其中包含Author实例的集合。因此,必须让 Castor 把每个author元素映射到一个Author实例(这一步差不多已经完成了),然后把所有实例组合成Book的Authors属性。

 

回页首

把元素映射到集合

为了映射图书和作者的关系,需要把几个元素(XML 文档中的每个author)映射到一个集合,然后把这个集合分配给Book的Authors属性。

首先使用field元素,因为确实要映射到Book的一个字段。还要把name属性的值指定为 “Authors”,因为这是Book中将映射到的属性:

<field name="Authors">

</field>

接下来,需要提供属性的类型。您可能认为这应该是集合类型。但是,实际上希望指定集合中每个成员的类型。所以类型应该是 ibm.xml.castor.Author。您将会获得 ibm.xml.castor.Author 类的实例,Castor 将把这些实例放到Authors属性中:

下面是关键之处:使用collection属性指定这个属性是一个集合。这个属性的值是集合的类型。Castor 当前只支持两个值:vector(代表列表类型)和array(代表数组类型)。通过标准的 Java 集合 API(比如next()等调用)访问第一种集合;管理第二种集合的方法与 Java 数组相似,按照索引来访问它们,比如ar[2]。在这个示例中,因为 Java 类型是List,所以使用vector:

如果指定了collection属性,Castor 就知道应该用与type属性对应的值构建这个集合。因此,这里的Authors属性应该是ibm.xml.castor.Author类型的实例的集合。

现在只剩下一步了:指定获取这些Author实例的来源。这要使用bind-xml元素:

<bind-xml name="author" />

所有工作都完成了;现在形成了一个完整的映射文件。最终的文件应该像清单 6 这样。

清单 6. 完整的映射文件

<?xml version="1.0"?>

<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"

"http://castor.org/mapping.dtd">

<mapping>

<class name="ibm.xml.castor.Book">

<map-to xml="book" />

<field name="Title" type="java.lang.String">

<bind-xml name="title" node="element" location="book-info" />

</field>

<field name="Isbn" type="java.lang.String">

<bind-xml name="isbn" node="element" location="book-info" />

</field>

<field name="Authors" type="ibm.xml.castor.Author" collection="vector">

<bind-xml name="author" />

</field>

</class>

<class name="ibm.xml.castor.Author">

<field name="FirstName" type="java.lang.String">

<bind-xml name="first" node="attribute" location="name" />

</field>

<field name="LastName" type="java.lang.String">

<bind-xml name="last" node="attribute" location="name" />

</field>

</class>

</mapping>

 

回页首

在程序中使用映射文件

最后,需要在解组过程中使用这个映射文件。以前,我们静态地使用Unmarshaller类,通过调用Unmarshaller.unmarshal()把 XML 转换为 Java 代码。但是,因为现在要使用映射文件,所以需要创建一个Unmarshaller实例并设置一些选项。清单 7 给出的类处理从 XML 文档到 Java 对象的解组过程。

清单 7. 用映射文件进行解组

package ibm.xml.castor;import java.io.FileReader;import java.util.Iterator;import java.util.List;import org.exolab.castor.mapping.Mapping;import org.exolab.castor.xml.Unmarshaller;public class BookMapUnmarshaller { public static void main(String[] args) { Mapping mapping = new Mapping(); try { mapping.loadMapping("book-mapping.xml"); FileReader reader = new FileReader("book.xml");Unmarshaller unmarshaller = new Unmarshaller(Book.class);unmarshaller.setMapping(mapping);Book book = (Book)unmarshaller.unmarshal(reader);System.out.println("Book ISBN: " + book.getIsbn()); System.out.println("Book Title: " + book.getTitle()); List authors = book.getAuthors(); for (Iterator i = authors.iterator(); i.hasNext(); ) { Author author = (Author)i.next(); System.out.println("Author: " + author.getFirstName() + " " + author.getLastName()); } } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(System.err); } }}

与前两篇文章中的解组器相比,这里的更改非常少。首先,创建一个Unmarshaller实例,使用的参数是 Book.class。这告诉解组器要解组的顶级类是哪个类。注意,这个顶级 Java 类对应于使用map-to元素的 mapping 元素。然后设置映射,最后调用unmarshal()的非静态版本。

现在完成了!这个过程与以前的过程差异并不大。作为练习,您可以自己试着编写把 Java 代码编组为 XML 的代码。请参考前一篇文章中的BookMarshaller类并设置映射文件,然后尝试在 XML 和 Java 代码之间来回转换。

 

回页首

结束语

数据绑定最终关注的是数据,而不是存储数据的格式。对于大多数 Java 程序员来说,处理 Java 对象是很容易的,而通过数据绑定,能够同样轻松地把来自各种来源(尤其是 XML)的数据转换为 Java 对象。另外,数据绑定环境中的映射甚至更进了一步:在填充 Java 对象时,可以非常灵活地处理数据源格式。因此,如果您喜欢数据绑定,那么一定也会喜欢映射;它使您能够绑定那些与您需要的命名约定不太相符的 XML 文档,也能够使用与您的 Java 对象不相符的结构。

对于数据人员,映射会带来同样的好处。当调用 Java 方法并保存在命名古怪的 XML 风格的变量中,或者 XML 文档中有多个元素全部映射到同一个类,那么不需要构建中间层就可以从 Java 类中取得所需的数据。最重要的是灵活性,能够对数据做您想做的事情,而不受框架或工具的限制。

 

回页首

后续内容

您已经看到了 Castor 在 XML 环境中提供了什么。但是,这仅仅触及到了 Castor 的皮毛。在下一篇文章中,将进一步扩展简单的 XML 数据绑定并研究 Castor 的 SQL 数据绑定设施。我们将把数据从 Java 类转移到 SQL 数据库中,再转移回来,而且不需要使用 JDBC。请复习一下 XML 和 SQL 知识,下个月我们将进一步体验数据绑定的威力。

学完下一篇文章(本系列的最后一篇)之后,您就能够用相同的 API 在 XML、Java 和 SQL 数据库之间进行转换。这甚至会带来比映射文件更大的灵活性。对于所有数据存储格式,可以使用单一 API 和相似的调用处理数据库、Java 对象和 XML 文档。实际上,对于那些了解 C# 的程序员来说,这听起来非常像 LINQ(LINQ 是 Visual C# 2008 中最新最热门的技术之一)。相似的功能已经用 Java 技术实现了,而且具有一个稳定的 API。很棒,不是吗?所以请继续研究 Castor,绑定数据,试试您能实现哪些功能。享受创造的乐趣吧!我们网上相见。

原文:http://www.ibm.com/developerworks/cn/xml/x-xjavacastor3/index.html

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2730/viewspace-3136062/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-12-18

  • 博文量
    492
  • 访问量
    12000