实现 Castor 数据绑定,第 3 部分: 模式之间的映射
2008-04-09 16:25
281 查看
使用 Castor 映射文件
级别: 高级
Brett D. McLaughlin, Sr. (brett@newInstance.com), 作家兼编辑, O'Reilly Media, Inc.
2008 年 3 月 03 日
在阅读了本系列的第 1 部分和第 2 部分之后,您应该已经熟悉如何使用 Castor 把 XML 转换成 Java™,然后再把 Java 转换回 XML。在本文中,将学习如何通过 Castor 映射文件增加灵活性。您将不再受到 XML 文档中的元素名或 Java 类中的成员变量名的限制。
与前一篇文章一样,本文也对您系统的设置情况和您的技能做一些假设。首先,需要按照本系列的第 1 部分中的描述下载并安装 Castor 的最新版本,设置类路径和相关的 Java 库(参见 参考资料 中本系列第一篇文章的链接)。然后,按照第 2 部分中的描述,熟悉 Castor 的基本编组和解组设施。
所以,您应该能够使用 Castor 提取出 XML 文档中的数据,并使用自己的 Java 类处理数据。用数据绑定术语来说,这称为解组(unmarshalling)。反向的过程称为编组(marshalling):您应该能够把 Java 类的成员变量中存储的数据转换为 XML 文档。如果您还不熟悉 Castor 的解组器和编组器,那么应该阅读 第 2 部分(参见 参考资料 中的链接)。
初看上去,您似乎已经掌握了有效地使用 Castor 所需了解的所有过程:设置、编组和解组。但是,您到目前为止学到的所有东西只适用于所谓的理想环境。在这样的环境中,每个人编写的 XML 都是完美的,其中的元素名是有意义的,比如 “title” 和 “authorAddress”,而不是 “t” 或 “aa”。Java 类是按照有组织的方式创建的,采用单数作为类名(比如 “Book”),采用单数名词作为成员变量名(比如 “isbn” 和 “price”)。另外,数据类型也是正确的:没有开发人员把
但是,大多数程序员所处的环境并不完美(我真想找到一个能够把我送到完美世界的魔法衣厨)。在大多数程序员所处的环境中有许多不理想的情况:XML 文档常常有糟糕的元素名和属性名,还要应付名称空间问题。元素数据存储在属性中,一些数据甚至由管道符或分号分隔。
Java 类是继承的,对它们进行重新组织在时间和工作量方面的成本可能会超过带来的好处。这些类常常无法简洁地映射到 XML 模式(认为 XML 和数据人员会与 Java 程序员相互妥协的想法也是非常不可思议的),而且在某些情况下,即使实现了简洁映射,也肯定不会跨所有类和数据。XML 元素名可能不合适,许多 Java 变量名也可能不合适。甚至可能遇到使用 Hungarian 表示法的名称,按照这种表示法,所有成员变量都以 “m” 开头,比如
在这些情况下,您目前学到的数据绑定方法就无能为力了。XML 文档中可能会出现 Hungarian 风格的元素名,Java 类中也可能出现没有意义的结构。这种情况是无法接受的。如果不能按照您希望的方式获取和操作 XML 文档的数据,那么 Castor(或任何数据绑定框架)又有什么意义呢?
首先要注意,在 Castor 或任何其他数据绑定框架中,使用映射文件都要花一些时间。必须先学习一些新语法。尽管映射文件使用 XML 格式(大多数框架都是这样的),但是您需要学习一些新元素和属性。还必须做一些测试,确保 XML 和 Java 代码之间的相互转换产生您希望的结果。最后,如果亲自指定映射,而不是让框架处理映射,就可能在数据绑定中遇到更多的错误。例如,如果希望让框架把 XML 中的
在学习使用映射文件之前,应该确定确实需要这么做。如果掌握了映射文件,但是却不使用它,那就是浪费时间。但是,映射确实有一些优点。
前面曾经提到,在把 XML 转换为 Java 代码时,大小写可能会导致错误。在 XML 中,最常用的做法是名称全部小写并加连字符,比如
是的,这似乎很明显。既然可以调整 XML 到 Java 的命名转换,反过来肯定也可以:在把 Java 类和属性包含的数据转换为 XML 时,可以修改 Java 名称。但是,有一个更重要,也更微妙的好处:不再受到 Java 类名和包名的限制。
这很可能成为一个组织问题。例如,在大多数情况下,XML 中的嵌套元素转换为类结构,最内层的嵌套元素转换成类属性(成员变量)。看一下清单 1 中的 XML:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0" encoding="UTF-8"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<authors total-sales="0">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<last-name>Finder</last-name>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<first-name>Joseph</first-name>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</authors>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<isbn>9780312347482</isbn>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<title>Power Play</title>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Castor(或任何其他数据绑定框架)可能假设您需要一个
映射允许我们在 Java-XML 转换的两端指定命名方式。我们不希望由于 XML 文档的原因修改 Java 代码,同样不愿意修改 XML 结构来适应 Java 类和成员变量。另外,Java 包也会增加复杂性。尽管在 Castor 中包并不是大问题,但是仍然必须在编组的 XML 中存储 Java 类和包的相关信息,这对于业务逻辑(Java 类)和数据(XML)的隔离很不利。映射可以解决所有这些问题。
前两个问题(对 XML 和 Java 代码的限制)实际上与一个更大的问题相关。大多数情况下,您已经有了一组 Java 对象和一个或多个 XML 文档。因此,不具备前两篇文章中的那种自由度:不能让 Castor 根据它自己的规则把 Java 代码解组为 XML,或者为 XML 文档生成 Java 类。
相反,更为常见的情况是,您需要把一种新技术 — 数据绑定 — 添加到现有的结构中。在这种情况下,映射文件就是使用数据绑定的关键。在两个 “端点”(当前的对象模型和当前的 XML 结构)固定的情况下,映射使我们仍然能够把这两者的数据联系起来。简而言之,良好的映射系统使数据绑定能够在真实环境中发挥作用,而不仅仅停留在理论上。
我们先来看一个简单的映射场景。在前一篇文章中,我们开发了
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package ibm.xml.castor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.LinkedList;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.List;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Book ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//** The book's ISBN */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//** The book's title */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//** The authors' names */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private List<Author> authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Book() ...{ }
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Book(String isbn, String title, List<Author> authors) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.isbn = isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.title = title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.authors = authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Book(String isbn, String title, Author author) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.isbn = isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.title = title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.authors = new LinkedList<Author>();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
authors.add(author);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setIsbn(String isbn) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.isbn = isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getIsbn() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setTitle(String title) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.title = title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getTitle() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setAuthors(List<Author> authors) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.authors = authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public List<Author> getAuthors() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void addAuthor(Author author) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
authors.add(author);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
清单 3 是
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package ibm.xml.castor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Author ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String firstName, lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Author() ...{ }
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Author(String firstName, String lastName) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.firstName = firstName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.lastName = lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setFirstName(String firstName) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.firstName = firstName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setLastName(String lastName) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.lastName = lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getFirstName() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return firstName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getLastName() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
注意:与前一篇文章相比,惟一的修改是在
这一次不使用前一篇文章中的 XML,而是使用一个不太容易映射的 XML 文档。清单 4 给出希望绑定到 清单 2 和 清单 3 中的 Java 类的 XML 文档。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0" encoding="UTF-8"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<name first="Douglas" last="Preston" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<name first="Lincoln" last="Child" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<book-info>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<isbn>9780446618502</isbn>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<title>The Book of the Dead</title>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</book-info>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
在处理映射文件语法或 Castor 的 API 之前,第一个任务是判断需要把 XML(清单 4)中的哪些数据绑定到 Java 类(清单 2 和 清单 3)。请考虑一会儿。
下面简要总结一下这个 XML 文档应该如何映射到 Java 类:
每个
每个
对于每个
对于每个
其中一些映射您已经知道如何实现了。例如,
这里还有一些元素和属性并不直接映射到 Java 对象模型。
这种情况非常适合使用映射文件。它使我们能够使用这种 XML(包含我们需要的数据,但是结构不符合希望),仍然能够把文档中的数据放到 Java 对象中。而且,映射文件本身并不难编写。
Castor 中的映射是通过使用映射文件(mapping file) 实现的。映射文件仅仅是一个 XML 文档,它提供了如何在 Java 代码和 XML 之间进行转换的相关信息。因为您熟悉 XML,所以您会发现编写映射文件是非常容易的。实际上,对于简单的映射(只需修改元素名和 Java 类或成员变量的名称),只需一点儿时间就能编写好映射文件。
然后,当进行编组和解组时(前两篇文章已经介绍过如何在程序中进行编组和解组),Castor 会使用这个文件。只需对 Castor 多做一个 API 调用;其他代码都是一样的。
Castor 映射文件的开始是一个普通的 XML 文档,然后是根元素
清单 5 给出最基本的映射文件。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!-- All your mappings go here -->
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
这个文件显然没有实质性内容,但它是所有映射文件的起点。
建立基本的映射文件之后,差不多总是先要把一个 Java 类映射到一个 XML 元素。在这个示例中,需要把
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
现在,可以使用
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
这非常简单。实际上,到目前为止,这个映射文件只实现 Castor 的默认操作。除非由于以下两个原因,否则可以删除这个部分并让 Castor 处理这个任务:
需要指定如何填充
如果使用映射文件,那么最好指定所有内容 的映射方式。这会更明确 XML 和 Java 代码之间的配合。
有了基本的类到元素的映射之后,就可以开始把
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
在这里要注意两点。首先,提供了属性名(在这个示例中是 “title”)。这是属性(property) 名,而不是成员变量名。换句话说,Castor 通过调用
要注意的第二点是
在
但是,这里需要解决一个问题:书名和 ISBN 嵌套在
当遇到这种情况时 — 一个类中的一个字段并不直接映射到与这个类对应的 XML 元素中的数据 — 就需要在
因此,在这个示例中,希望把
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
然后为书的 ISBN 添加另一个字段映射:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
现在,
按照相同的方式对其他类进行映射。惟一的差异是在其他类中不需要使用
需要把
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<name first="Lincoln" last="Child" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</author>
惟一需要注意的是,这里并不用两个元素分别包含名字和姓氏,而是使用一个带两个属性的元素。但是,前面已经使用过
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="FirstName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="first" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="LastName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="last" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
现在,您应该很容易看懂这些代码。这里指定了映射到的类(
如果看一下 上面 的 XML,就会注意到并没有指定
如果每本书只有一位作者,那么在
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Author" type="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="author" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="FirstName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="first" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="LastName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="last" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
在这种情况下,把这一映射放在映射文件的图书部分中,因为映射的是属于
但是,问题在于
为了映射图书和作者的关系,需要把几个元素(XML 文档中的每个
首先使用
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
接下来,需要提供属性的类型。您可能认为这应该是集合类型。但是,实际上希望指定集合中每个成员的类型。所以类型应该是 ibm.xml.castor.Author。您将会获得 ibm.xml.castor.Author 类的实例,Castor 将把这些实例放到
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
下面是关键之处:使用
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author" collection="vector">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
如果指定了
现在只剩下一步了:指定获取这些
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author" collection="vector">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="author" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
所有工作都完成了;现在形成了一个完整的映射文件。最终的文件应该像清单 6 这样。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author" collection="vector">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="author" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="FirstName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="first" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="LastName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="last" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
最后,需要在解组过程中使用这个映射文件。以前,我们静态地使用
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package ibm.xml.castor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.io.FileReader;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.Iterator;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.List;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.exolab.castor.mapping.Mapping;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.exolab.castor.xml.Unmarshaller;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class BookMapUnmarshaller ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public static void main(String[] args) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Mapping mapping = new Mapping();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
try ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
mapping.loadMapping("book-mapping.xml");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
FileReader reader = new FileReader("book.xml");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Unmarshaller unmarshaller = new Unmarshaller(Book.class);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
unmarshaller.setMapping(mapping);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Book book = (Book)unmarshaller.unmarshal(reader);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Book ISBN: " + book.getIsbn());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Book Title: " + book.getTitle());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
List authors = book.getAuthors();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
for (Iterator i = authors.iterator(); i.hasNext(); ) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Author author = (Author)i.next();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Author: " + author.getFirstName() + " " +
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
author.getLastName());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
} catch (Exception e) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.err.println(e.getMessage());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
e.printStackTrace(System.err);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
与前两篇文章中的解组器相比,这里的更改非常少。首先,创建一个
现在完成了!这个过程与以前的过程差异并不大。作为练习,您可以自己试着编写把 Java 代码编组为 XML 的代码。请参考前一篇文章中的
数据绑定最终关注的是数据,而不是存储数据的格式。对于大多数 Java 程序员来说,处理 Java 对象是很容易的,而通过数据绑定,能够同样轻松地把来自各种来源(尤其是 XML)的数据转换为 Java 对象。另外,数据绑定环境中的映射甚至更进了一步:在填充 Java 对象时,可以非常灵活地处理数据源格式。因此,如果您喜欢数据绑定,那么一定也会喜欢映射;它使您能够绑定那些与您需要的命名约定不太相符的 XML 文档,也能够使用与您的 Java 对象不相符的结构。
对于数据人员,映射会带来同样的好处。当调用 Java 方法并保存在命名古怪的 XML 风格的变量中,或者 XML 文档中有多个元素全部映射到同一个类,那么不需要构建中间层就可以从 Java 类中取得所需的数据。最重要的是灵活性,能够对数据做您 想做的事情,而不受框架或工具的限制。
级别: 高级
Brett D. McLaughlin, Sr. (brett@newInstance.com), 作家兼编辑, O'Reilly Media, Inc.
2008 年 3 月 03 日
在阅读了本系列的第 1 部分和第 2 部分之后,您应该已经熟悉如何使用 Castor 把 XML 转换成 Java™,然后再把 Java 转换回 XML。在本文中,将学习如何通过 Castor 映射文件增加灵活性。您将不再受到 XML 文档中的元素名或 Java 类中的成员变量名的限制。
与前一篇文章一样,本文也对您系统的设置情况和您的技能做一些假设。首先,需要按照本系列的第 1 部分中的描述下载并安装 Castor 的最新版本,设置类路径和相关的 Java 库(参见 参考资料 中本系列第一篇文章的链接)。然后,按照第 2 部分中的描述,熟悉 Castor 的基本编组和解组设施。
所以,您应该能够使用 Castor 提取出 XML 文档中的数据,并使用自己的 Java 类处理数据。用数据绑定术语来说,这称为解组(unmarshalling)。反向的过程称为编组(marshalling):您应该能够把 Java 类的成员变量中存储的数据转换为 XML 文档。如果您还不熟悉 Castor 的解组器和编组器,那么应该阅读 第 2 部分(参见 参考资料 中的链接)。
初看上去,您似乎已经掌握了有效地使用 Castor 所需了解的所有过程:设置、编组和解组。但是,您到目前为止学到的所有东西只适用于所谓的理想环境。在这样的环境中,每个人编写的 XML 都是完美的,其中的元素名是有意义的,比如 “title” 和 “authorAddress”,而不是 “t” 或 “aa”。Java 类是按照有组织的方式创建的,采用单数作为类名(比如 “Book”),采用单数名词作为成员变量名(比如 “isbn” 和 “price”)。另外,数据类型也是正确的:没有开发人员把
price的数据类型设置为
int而不是
float,或者使用
char数组存储字符串数据(这是 C 语言的做法)。
但是,大多数程序员所处的环境并不完美(我真想找到一个能够把我送到完美世界的魔法衣厨)。在大多数程序员所处的环境中有许多不理想的情况:XML 文档常常有糟糕的元素名和属性名,还要应付名称空间问题。元素数据存储在属性中,一些数据甚至由管道符或分号分隔。
Java 类是继承的,对它们进行重新组织在时间和工作量方面的成本可能会超过带来的好处。这些类常常无法简洁地映射到 XML 模式(认为 XML 和数据人员会与 Java 程序员相互妥协的想法也是非常不可思议的),而且在某些情况下,即使实现了简洁映射,也肯定不会跨所有类和数据。XML 元素名可能不合适,许多 Java 变量名也可能不合适。甚至可能遇到使用 Hungarian 表示法的名称,按照这种表示法,所有成员变量都以 “m” 开头,比如
mTitle。这很不好看。
在这些情况下,您目前学到的数据绑定方法就无能为力了。XML 文档中可能会出现 Hungarian 风格的元素名,Java 类中也可能出现没有意义的结构。这种情况是无法接受的。如果不能按照您希望的方式获取和操作 XML 文档的数据,那么 Castor(或任何数据绑定框架)又有什么意义呢?
首先要注意,在 Castor 或任何其他数据绑定框架中,使用映射文件都要花一些时间。必须先学习一些新语法。尽管映射文件使用 XML 格式(大多数框架都是这样的),但是您需要学习一些新元素和属性。还必须做一些测试,确保 XML 和 Java 代码之间的相互转换产生您希望的结果。最后,如果亲自指定映射,而不是让框架处理映射,就可能在数据绑定中遇到更多的错误。例如,如果希望让框架把 XML 中的
fiddler元素映射到 Java 代码中的
violin属性,但是错误地声明这个属性是在
player类中(应该是在
Player类中),那么就会遇到错误。因此,在亲自指定映射时,必须非常注意拼写、大小写、下划线、单引号和双引号。
在学习使用映射文件之前,应该确定确实需要这么做。如果掌握了映射文件,但是却不使用它,那就是浪费时间。但是,映射确实有一些优点。
前面曾经提到,在把 XML 转换为 Java 代码时,大小写可能会导致错误。在 XML 中,最常用的做法是名称全部小写并加连字符,比如
first-name。有时候,甚至会看到
first_name。这样的名称会转换为很难看的 Java 属性名;没人愿意在代码中调用
getFirst-name()。实际上,在大多数由程序员(而不是 XML 开发人员或数据管理员)编写的文档中,往往使用驼峰式(camel-case)命名法,比如
firstName。通过使用映射文件,很容易把 XML 风格的名称(比如
first-name)映射为 Java 风格的名称(比如
firstName)。最棒的一点是,不需要强迫 XML 人员像 Java 程序员那样思考,这往往比学习新的映射语法困难得多。
是的,这似乎很明显。既然可以调整 XML 到 Java 的命名转换,反过来肯定也可以:在把 Java 类和属性包含的数据转换为 XML 时,可以修改 Java 名称。但是,有一个更重要,也更微妙的好处:不再受到 Java 类名和包名的限制。
这很可能成为一个组织问题。例如,在大多数情况下,XML 中的嵌套元素转换为类结构,最内层的嵌套元素转换成类属性(成员变量)。看一下清单 1 中的 XML:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0" encoding="UTF-8"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<authors total-sales="0">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<last-name>Finder</last-name>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<first-name>Joseph</first-name>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</authors>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<isbn>9780312347482</isbn>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<title>Power Play</title>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
Castor(或任何其他数据绑定框架)可能假设您需要一个
Book类,这个类引用几个
Author类实例。author 类应该有成员变量
lastName和
firstName(这里会出现前面提到的命名问题,
Author中的成员变量应该是
last-name,还是
lastName?对于名字也有这个问题)。但是,如果这不是您希望的结果,应该怎么办?例如,您可能在一个称为
Person或
Professional的类中存储所有作家、会议演讲人和教授。在这种情况下就真有麻烦了,而且您不会愿意全面修改 XML 元素的结构和名称来解决这个问题。实际上,在这种情况下,要想原样保持 XML,使用映射是惟一的办法。
映射允许我们在 Java-XML 转换的两端指定命名方式。我们不希望由于 XML 文档的原因修改 Java 代码,同样不愿意修改 XML 结构来适应 Java 类和成员变量。另外,Java 包也会增加复杂性。尽管在 Castor 中包并不是大问题,但是仍然必须在编组的 XML 中存储 Java 类和包的相关信息,这对于业务逻辑(Java 类)和数据(XML)的隔离很不利。映射可以解决所有这些问题。
前两个问题(对 XML 和 Java 代码的限制)实际上与一个更大的问题相关。大多数情况下,您已经有了一组 Java 对象和一个或多个 XML 文档。因此,不具备前两篇文章中的那种自由度:不能让 Castor 根据它自己的规则把 Java 代码解组为 XML,或者为 XML 文档生成 Java 类。
相反,更为常见的情况是,您需要把一种新技术 — 数据绑定 — 添加到现有的结构中。在这种情况下,映射文件就是使用数据绑定的关键。在两个 “端点”(当前的对象模型和当前的 XML 结构)固定的情况下,映射使我们仍然能够把这两者的数据联系起来。简而言之,良好的映射系统使数据绑定能够在真实环境中发挥作用,而不仅仅停留在理论上。
我们先来看一个简单的映射场景。在前一篇文章中,我们开发了
Book和
Author类。清单 2 是
Book类。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package ibm.xml.castor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.LinkedList;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.List;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Book ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//** The book's ISBN */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//** The book's title */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//** The authors' names */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private List<Author> authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Book() ...{ }
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Book(String isbn, String title, List<Author> authors) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.isbn = isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.title = title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.authors = authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Book(String isbn, String title, Author author) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.isbn = isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.title = title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.authors = new LinkedList<Author>();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
authors.add(author);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setIsbn(String isbn) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.isbn = isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getIsbn() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return isbn;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setTitle(String title) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.title = title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getTitle() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return title;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setAuthors(List<Author> authors) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.authors = authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public List<Author> getAuthors() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return authors;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void addAuthor(Author author) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
authors.add(author);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
清单 3 是
Author类。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package ibm.xml.castor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Author ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String firstName, lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Author() ...{ }
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public Author(String firstName, String lastName) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.firstName = firstName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.lastName = lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setFirstName(String firstName) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.firstName = firstName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void setLastName(String lastName) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.lastName = lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getFirstName() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return firstName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public String getLastName() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return lastName;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
注意:与前一篇文章相比,惟一的修改是在
Author中删除了总销售额(
totalSales变量)。我发现它的意义不大,所以在这个版本中删除了它。
这一次不使用前一篇文章中的 XML,而是使用一个不太容易映射的 XML 文档。清单 4 给出希望绑定到 清单 2 和 清单 3 中的 Java 类的 XML 文档。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0" encoding="UTF-8"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<name first="Douglas" last="Preston" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<name first="Lincoln" last="Child" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<book-info>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<isbn>9780446618502</isbn>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<title>The Book of the Dead</title>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</book-info>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</book>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
在处理映射文件语法或 Castor 的 API 之前,第一个任务是判断需要把 XML(清单 4)中的哪些数据绑定到 Java 类(清单 2 和 清单 3)。请考虑一会儿。
下面简要总结一下这个 XML 文档应该如何映射到 Java 类:
book元素应该映射到
Book类的一个实例。
每个
author元素应该映射到
Author类的一个实例。
每个
Author实例应该添加到
Book实例中的
authors列表中。
对于每个
Author实例,
firstName应该设置为
name元素上的
first属性的值。
对于每个
Author实例,
lastName应该设置为
name元素上的
last属性的值。
Book实例的 ISBN 应该设置为
book-info元素中嵌套的
isbn元素的值。
Book实例的书名应该设置为
book-info元素中嵌套的
title元素的值。
其中一些映射您已经知道如何实现了。例如,
book到
Book类实例的映射是标准的,Castor 会默认处理这个任务。但是,也有一些新东西,比如说作者。尽管把一个
author元素映射到一个
Author实例没什么问题,但是没有分组元素,比如
authors,它清楚地显示出所有作者属于
Book实例中的一个集合。
这里还有一些元素和属性并不直接映射到 Java 对象模型。
Author类包含表示名字和 姓氏的变量,但是在 XML 中只用一个元素(
name)表示作者姓名,这个元素有两个属性。
book-info元素中嵌套的书名和 ISBN 并不映射到任何 Java 对象。
这种情况非常适合使用映射文件。它使我们能够使用这种 XML(包含我们需要的数据,但是结构不符合希望),仍然能够把文档中的数据放到 Java 对象中。而且,映射文件本身并不难编写。
Castor 中的映射是通过使用映射文件(mapping file) 实现的。映射文件仅仅是一个 XML 文档,它提供了如何在 Java 代码和 XML 之间进行转换的相关信息。因为您熟悉 XML,所以您会发现编写映射文件是非常容易的。实际上,对于简单的映射(只需修改元素名和 Java 类或成员变量的名称),只需一点儿时间就能编写好映射文件。
然后,当进行编组和解组时(前两篇文章已经介绍过如何在程序中进行编组和解组),Castor 会使用这个文件。只需对 Castor 多做一个 API 调用;其他代码都是一样的。
Castor 映射文件的开始是一个普通的 XML 文档,然后是根元素
mapping。还可以引用 Castor 映射 DTD。这样就可以检验文档,确保结构和语法没有任何问题。这会大大简化对映射的调试。
清单 5 给出最基本的映射文件。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!-- All your mappings go here -->
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
这个文件显然没有实质性内容,但它是所有映射文件的起点。
建立基本的映射文件之后,差不多总是先要把一个 Java 类映射到一个 XML 元素。在这个示例中,需要把
Book类映射到
book元素中的数据。映射文件首先考虑类,所以需要添加一个
class元素,并在这个元素的
name属性中指定完全限定的 Java 类名,比如:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
现在,可以使用
map-to元素和
xml属性指定这个类要映射到的 XML 元素。这个元素嵌套在 XML 元素映射到的 Java 类(完全限定,包括包名)的
class元素中,比如:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
这非常简单。实际上,到目前为止,这个映射文件只实现 Castor 的默认操作。除非由于以下两个原因,否则可以删除这个部分并让 Castor 处理这个任务:
需要指定如何填充
Book中的某些字段,比如书名和 ISBN。
如果使用映射文件,那么最好指定所有内容 的映射方式。这会更明确 XML 和 Java 代码之间的配合。
有了基本的类到元素的映射之后,就可以开始把
Book类的字段映射到 XML 文档中的特定元素。Castor 映射文件使用
field元素指定要使用的 Java 成员变量,使用其中嵌套的
bind-xml元素指定映射到的 XML 元素。因此,下面的代码指定把
Book类中的
title变量映射到
book元素中嵌套的
title元素:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![]() |
|
set[PropertyName]()来使用这个属性名。如果提供属性名 “foo”,Castor 就会尝试调用
setfoo()— 这可能不是您希望的情况。因此,要仔细注意大小写,并使用属性 名而不是 Java 类中的变量名。
要注意的第二点是
type属性。这个属性向 Castor 说明数据究竟是什么类型的。在这个示例中,这很简单;但是在某些情况下,希望将以 XML 文本式数据存储的数字存储为整数、小数或者只是字符串,这时指定正确的数据类型就很重要了。另外,类型应该使用完全限定的 Java 类名,比如
java.lang.String。
在
bind-xml元素中,指定要绑定到的 XML 元素的名称(在这个示例中是 “title”),并使用
node属性指定是绑定到元素还是绑定到属性。这样就可以轻松地使用元素和属性数据,只需在映射文件中稍做修改即可。
但是,这里需要解决一个问题:书名和 ISBN 嵌套在
book-info元素中,而不是直接嵌套在
book元素中。所以需要在映射文件中指出这一情况。
当遇到这种情况时 — 一个类中的一个字段并不直接映射到与这个类对应的 XML 元素中的数据 — 就需要在
bind-xml元素中使用
location属性。这个属性的值应该是 XML 文档中包含您希望绑定到的数据的元素。如果绑定到元素数据,它就应该是目标元素的父 元素;如果绑定到属性数据,它就应该是包含这个属性的 元素。
因此,在这个示例中,希望把
Book类的书名属性绑定到
title元素的值,而这个元素嵌套在
book-info元素中。下面是映射方法:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
然后为书的 ISBN 添加另一个字段映射:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
现在,
Book类的属性都已经设置好了。该处理
Author类了。
按照相同的方式对其他类进行映射。惟一的差异是在其他类中不需要使用
map-to元素。
需要把
Author类中的字段映射到
author元素。请记住,下面是要处理的 XML 片段:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<author>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<name first="Lincoln" last="Child" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</author>
惟一需要注意的是,这里并不用两个元素分别包含名字和姓氏,而是使用一个带两个属性的元素。但是,前面已经使用过
location属性(需要用这个属性指定
name元素是映射到的位置)和
node属性(可以在这里指定要绑定到属性数据,而不是元素)。所以在映射文件中需要以下代码:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="FirstName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="first" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="LastName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="last" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
现在,您应该很容易看懂这些代码。这里指定了映射到的类(
Author)和这个类上要映射的属性(
FirstName和
LastName)。对于每个属性,指定要查看的 XML 元素(都是
name)并指定需要的是属性数据。
如果看一下 上面 的 XML,就会注意到并没有指定
Author类应该映射到哪个 XML 元素。这是一个问题,因为 Castor 不会猜测您的意图;只要使用映射文件,最好指定所有映射信息。
如果每本书只有一位作者,那么在
Book类中可能有一个
Author属性。在这种情况下,可以在映射文件中插入以下代码:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Author" type="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="author" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="FirstName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="first" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="LastName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="last" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
在这种情况下,把这一映射放在映射文件的图书部分中,因为映射的是属于
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中将映射到的属性:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
接下来,需要提供属性的类型。您可能认为这应该是集合类型。但是,实际上希望指定集合中每个成员的类型。所以类型应该是 ibm.xml.castor.Author。您将会获得 ibm.xml.castor.Author 类的实例,Castor 将把这些实例放到
Authors属性中:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
下面是关键之处:使用
collection属性指定这个属性是一个集合。这个属性的值是集合的类型。Castor 当前只支持两个值:vector(代表列表类型)和 array(代表数组类型)。通过标准的 Java 集合 API(比如
next()等调用)访问第一种集合;管理第二种集合的方法与 Java 数组相似,按照索引来访问它们,比如
ar[2]。在这个示例中,因为 Java 类型是
List,所以使用 vector:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author" collection="vector">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
如果指定了
collection属性,Castor 就知道应该用与
type属性对应的值构建这个集合。因此,这里的
Authors属性应该是
ibm.xml.castor.Author类型的实例的集合。
现在只剩下一步了:指定获取这些
Author实例的来源。这要使用
bind-xml元素:
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author" collection="vector">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="author" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
所有工作都完成了;现在形成了一个完整的映射文件。最终的文件应该像清单 6 这样。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<?xml version="1.0"?>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
"http://castor.org/mapping.dtd">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<mapping>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Book">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<map-to xml="book" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Title" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="title" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Isbn" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="isbn" node="element" location="book-info" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="Authors" type="ibm.xml.castor.Author" collection="vector">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="author" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<class name="ibm.xml.castor.Author">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="FirstName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="first" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<field name="LastName" type="java.lang.String">
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
<bind-xml name="last" node="attribute" location="name" />
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</field>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</class>
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
</mapping>
最后,需要在解组过程中使用这个映射文件。以前,我们静态地使用
Unmarshaller类,通过调用
Unmarshaller.unmarshal()把 XML 转换为 Java 代码。但是,因为现在要使用映射文件,所以需要创建一个
Unmarshaller实例并设置一些选项。清单 7 给出的类处理从 XML 文档到 Java 对象的解组过程。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package ibm.xml.castor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.io.FileReader;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.Iterator;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.util.List;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.exolab.castor.mapping.Mapping;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.exolab.castor.xml.Unmarshaller;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class BookMapUnmarshaller ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public static void main(String[] args) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Mapping mapping = new Mapping();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
try ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
mapping.loadMapping("book-mapping.xml");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
FileReader reader = new FileReader("book.xml");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Unmarshaller unmarshaller = new Unmarshaller(Book.class);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
unmarshaller.setMapping(mapping);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Book book = (Book)unmarshaller.unmarshal(reader);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Book ISBN: " + book.getIsbn());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Book Title: " + book.getTitle());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
List authors = book.getAuthors();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
for (Iterator i = authors.iterator(); i.hasNext(); ) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Author author = (Author)i.next();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Author: " + author.getFirstName() + " " +
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
author.getLastName());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
} catch (Exception e) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.err.println(e.getMessage());
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
e.printStackTrace(System.err);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
与前两篇文章中的解组器相比,这里的更改非常少。首先,创建一个
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 数据绑定,第 2 部分: 编组和解组 XML
- 实现 Castor 数据绑定,第 2 部分: 编组和解组 XML
- 主流数据库之间对SQL:2003标准的不同实现方法比较(第六部分 基础数据类型之BOOLEAN)
- Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(7/19)
- PHP数据对象映射模式与实现简单的链式操作
- 实现Castor数据绑定,把 Java 对象绑定到 SQL 数据库
- Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(8/19)
- 使用逻辑数据PNPCE时,选择屏幕中实现单人模式和多人模式之间的切换
- Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(1/19)
- Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(9/19)
- 如何实现不同数据存储模式之间的数据转换
- 使用EF Oracle实现DevExpress绑定大数据的ServerMode模式
- MVVM模式和在WPF中的实现(二)数据绑定
- Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(2/19)
- Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(14/19)
- SDI文档模式下调用对话框实现在对话框上绘图操作,并且进行文档和对话框之间的数据传输
- 本文是笔者根据数据库编程经验,利用C++语言的模板、继承、授权、多态等面向对象特性,借鉴命令模式,实现了对象在关系数据中的存储,降低应用系统与数据库之间的耦合,提高开发效率。
- 主流数据库之间对SQL:2003标准的不同实现方法比较(第四部分 查询结果集中间n行数据)
- vue中的双向数据绑定的实现(数据劫持,结合发布者---订阅者模式)
- Eclipse 中的 JFace 数据绑定,第 3 部分: 使用高级功能(3/19)