`

Castor功能与应用参考(二)- XML映射

 
阅读更多
索引
2.1 概述
1. 示例需求
在运行下文中讲述的示例时,用户需要预先做一些准备工作。用户可以从castor网站上获取最新1.1.2.1版本包括castor-1.1.2.1.zip和castor-1.1.2.1-examples.zip解压到本地目录,在Eclipse中构建一个Java项目。然后将解压目录中的castor-1.1.2.1.jar,lib目录下的commons-logging-1.1.jar,log4j-1.2.13.jar和xerces-J_1.4.0.jar添加到项目的类路径中。
2. Castor XML映射概念
Castor XML 通过Mapping定义的方式简化了Java类和XML文档之间的绑定。尽管可以使用Castor默认的自省方式编组和解编Java对象,但是对于复杂的映射绑定,Mapping定义提供了更加细致的控制。同时,Mapping文件可以在一定程度上解耦合Java对象模型与XML文档,从而避免各自的变化给对方带来的影响。
2.1概述
Mpping文件本身也以XML文档格式定义。Mapping文档以Java对象模型为视角,用于描述Java对象如何映射为XML文档节点,Java对象中的字段属性如何映射为XML文档节点中的子节点或属性。
如上图所示,在Castor中,一个Java类映射为一个XML节点,Java类中的属性字段映射为XML节点下的子节点或者属性。描述上述映射的Mapping文件如下所示:
<?xml version="1.0"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
"http://castor.org/mapping.dtd">
<mapping>
<description>Description of the mapping</description>
<map-to xml="Person"/>
<class name="Person">
<field name="name" type="string">
<bind-xml name="name" node="element"/>
</field>
<field name="birthday" type="date">
<bind-xml name="birthday" node="element"/>
</field>
</class>
</mapping>
2.2编组过程
在Castor中,一个Java类必须映射为一个XML节点。当Castor编组一个Java对象的过程如下:首先,如果存在映射信息,从映射信息中确定该对象所对应的XML节点名称;如果不存在映射信息,则使用对象的类名作为XML节点名。然后,使用映射文件中字段<field>的映射信息确定Java对象中的一个字段属性如何转换为XML文档中的如下几种存在:
  • 一个属性
  • 一个节点
  • 一个节点的文本
  • 忽略(在映射文件中可以设定不编组某一字段属性,Castor将忽略该字段)
Castor遍历整个Java对象,如果发现一个Class类型的属性,则查找Mapping文件中的<class>节点定义。
如果在Mapping文件中找不到一个类的对应信息,默认情况下,Castor会分析这个类的元数据,采用一组默认的规则来定义要编组的字段属性所映射的XML文档元素。默认规则如下:
  • 所有原始数据类型,包括原始数据类型的对象封装类型(如Boolean,Short等)都编组为XML节点属性;
  • 所有其他对象类型都编组为文本或者节点;
2.3解编过程
在解编过程中,当Castor查找到一个XML文档节点时,Castor首先查找映射信息来决定如何解编XML文档为Java对象。如果不存在映射信息,Castor会使用XML节点的名称决定如何构建类(Class)实例,例如,如果节点的名称为”test-element”,在Mapping文件不存在时,Castor将构建一个名称为”TestElement”的类。然后,Castor根据映射文件中关于字段属性的映射信息处理该XML文档节点下的内容。
3. 映射文件定义详解
3.1Mapping文件的根节点
如上例XML Mapping文件所示,Mapping文件的根节点为<mapping><mapping>节点的Xml Schema定义为:
<xsd:element name="mapping">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element ref="include" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="class" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="key-generator" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<mapping>节点下的节点包括:
  • 一个<description>节点,可选的,用于添加描述信息
  • 一个或多个<include>节点,用于引用其他的映射文件
  • 一个或多个<class>节点,用于描述每一个定义MappingJava
  • 一个或多个<key-generator>节点,该节点在Castor JDO中使用,后续文档将详细解释
Mapping文件举例如下:
 <?xml version="1.0"?>
 <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
 "http://castor.org/mapping.dtd">
 <mapping>
 <description>Description of the mapping</description>
 <include href="other_mapping_file.xml"/>
 <class name="A">
 .........
 </class>
 <class name="B">
 .........
 </class>
 </mapping>
3.2<class>节点定义
<class>节点的Schema定义如下:
<xsd:element name="class">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element ref="cache-type" minOccurs="0"/>
<xsd:element ref="map-to" minOccurs="0"/>
<xsd:element ref="named-query" minOccurs="0" maxOccurs="unbounded"/>
<xsd:choice>
<xsd:element ref="field" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element ref="container" minOccurs="0" maxOccurs="unbounded"/>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:ID" use="required"/>
<xsd:attribute name="extends" type="xsd:IDREF" use="optional"/>
<xsd:attribute name="depends" type="xsd:IDREF" use="optional"/>
<xsd:attribute name="identity" type="xsd:NMTOKENS" use="optional"/>
<xsd:attribute name="access" use="optional" default="shared">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="read-only"/>
<xsd:enumeration value="shared"/>
<xsd:enumeration value="exclusive"/>
<xsd:enumeration value="db-locked"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="key-generator" type="xsd:string" use="optional"/>
<xsd:attribute name="auto-complete" type="xsd:boolean" use="optional" default="false"/>
<xsd:attribute name="verify-constructable" type="xsd:boolean" use="optional" default="true"/>
</xsd:complexType>
</xsd:element>
<class>节点包含了Java类与XML文档之间映射的所有信息。其中,详细描述了Java类中各个字段属性与XML文档元素的映射。
3.2.1 <class>节点的属性
Øname: 映射的Java类名称,使用类的全名,如”com.acme.MyClass”
Øextends: 只有在该类扩展其他类时,使用该参数指定扩展的类。如果被扩展的类未在该Mapping文件中指定,则不能使用该属性。
Ødepends: 在Castor JDO中指明类之间的依赖关系,用于表示数据库表中关联表的概念。
Øauto-complete: 如果该属性值为”true”,则Castor在处理该类时首先采用自省的方式决定该类的字段属性,然后使用Mapping文件中对该字段属性的设定覆盖自省方式的操作。auto-complete属性可以让Castor的默认自省处理方式与Mapping定义方式很好的结合,从而降低对包含很多字段的类进行复杂的设定操作。
Øidentity: 在Castor JDO中使用,用于描述该类实例的主键字段,详细信息参考Castor JDO部分。
Øaccess: 在Castor JDO中使用,详细信息参考Castor JDO部分。
Økey-generator: 在Castor JDO中使用,详细信息参考Castor JDO部分。
3.2.2 <class>节点的子节点
Ødescription可选的属性,用于对该类添加描述性信息
Øcache-type: 只在Castor JDO中使用,详细信息参考Castor JDO部分。
Ømap-to: 可选属性,如果XML中节点名称与类(Class)名称不同,则使用该节点设定。默认的,Castor会自动分析XML节点名称和类名称之间的映射,如对于Java类”XxxYyy”,Castor会自动映射为XML节点”xxx-yyy”。如果用户不希望Castor自动生成该名称,则可以使用<map-to>节点来指定XML映射名称。注意:<map-to>仅用于XML文档中的根节点。
Øfield节点下包含 零个或多个<field>节点。每个<field>节点用于描述Java类中的一个字段属性。<class>
<class>映射举例
下面的例子将Java类MyClass映射为XML文档中的节点’<data>’:
package mypackage
public class MyClass {
 public int foo;
 public String getBar() { ... }
 public void setBar(String bar) { ... }
}
如果用户希望输出的XML文档格式如下:
 <data foo-like="12">
 <something>...</something>
</data>
则用户需要以如下方式设定Mapping映射文件:
 <mapping>
 ...
 <class name="mypackage.MyClass">
 <map-to xml="data"/>
 <field name="foo" direct="true" ...>
 <bind-xml name="foo-like" node="attribute"/>
 </field>
 </field name="bar" ....>
 <bind-xml name="something" node="element"/>
 </field>
 </class>
 ...
</mapping>
3.3<map-to>节点定义
<map-to>节点的Schema定义如下:
<xsd:element name="map-to">
<xsd:complexType>
<xsd:attribute name="table" type="xsd:NMTOKEN" use="optional"/>
<xsd:attribute name="xml" type="xsd:string" use="optional"/>
<xsd:attribute name="ns-uri" type="xsd:string" use="optional"/>
<xsd:attribute name="ns-prefix" type="xsd:NMTOKEN" use="optional"/>
<xsd:attribute name="element-definition" type="xsd:boolean" use="optional" default="false"/>
<xsd:attribute name="ldap-dn" type="xsd:string" use="optional"/>
<xsd:attribute name="ldap-oc" type="xsd:string" use="optional"/>
</xsd:complexType>
</xsd:element>
<map-to>节点用于指定给定Java类与XML文档节点的映射。<map-to>节点只用于XML文档根节点,如果该节点未在Mapping文件中设定,则Castor采用如下处理策略:
Ø在编组过程中,通过Java类名称命名XML文档根节点名,如Java类”XxxYyy”映射为XML节点”xxx-yyy”
Ø在解编过程中,通过XML文档根节点名称确定Java类名称,如XML节点”test-element”映射为Java类”TestElement”
用户可以在castor.properties中指定Castor在Java类名称与XML文档节点名之间的转换策略。<map-to>节点的属性包括:
Øxml类映射的XML节点名称Java
Øns-uri:XML 节点的名称空间URI
Øns-prefix:XML 节点的名称空间前缀
Øelement-definition:True if the descriptor as created from a schema definition that was of type element (as opposed to a <complexType> definition). This only is useful in the context of source code generation
Øldap-dn: 在Castor XML中不使用该属性
Øldap-oc: 在Castor XML中不使用该属性
3.4< field>节点定义
< field>节点的Schema定义如下:
<xsd:element name="field">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="description" type="xsd:string" minOccurs="0"/>
<xsd:element ref="sql" minOccurs="0"/>
<xsd:element ref="bind-xml" minOccurs="0"/>
<xsd:element ref="ldap" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="type" type="xsd:string" use="optional"/>
<xsd:attribute name="required" type="xsd:boolean" use="optional" default="false"/>
<xsd:attribute name="transient" type="xsd:boolean" use="optional" default="false"/>
<xsd:attribute name="direct" type="xsd:boolean" use="optional" default="false"/>
<xsd:attribute name="lazy" type="xsd:boolean" use="optional" default="false"/>
<xsd:attribute name="container" type="xsd:boolean" use="optional"/>
<xsd:attribute name="get-method" type="xsd:string" use="optional"/>
<xsd:attribute name="has-method" type="xsd:string" use="optional"/>
<xsd:attribute name="set-method" type="xsd:string" use="optional"/>
<xsd:attribute name="create-method" type="xsd:string" use="optional"/>
<xsd:attribute name="handler" type="xsd:string" use="optional"/>
<xsd:attribute name="collection" use="optional">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="array"/>
<xsd:enumeration value="vector"/>
<xsd:enumeration value="arraylist"/>
<xsd:enumeration value="hashtable"/>
<xsd:enumeration value="collection"/>
<xsd:enumeration value="set"/>
<xsd:enumeration value="map"/>
<xsd:enumeration value="enumerate"/>
<xsd:enumeration value="sortedset"/>
<xsd:enumeration value="iterator"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="comparator" type="xsd:string" use="optional"/>
<xsd:attribute name="identity" type="xsd:boolean" use="optional" default="false"/>
</xsd:complexType>
</xsd:element>
<field>节点用于描述如何编组/解编Java对象中的字段属性。Castor可以从<field>节点描述中的”name”属性确定Java字段的名称;可以从<field>节点描述中的”type”和”collection”属性确定Java字段的类型;可以从<field>节点描述中的”direct”,”get-method”和”set-method”属性确定Java字段的访问方法。通过上述信息,Castor能够操作Java类中的字段属性。
Castor通过以下两个规则来判定某一字段的类型签名:
  • 检查<field>节点中的“类型”属性(”type””collection”
如果<field>节点中没有”collection”属性,”type”属性指定的类型即为该字段的Java类型。”type”属性值既可以是Java对象类型的全限定名(包含包名称),也可以是Castor定义的一系列简称。Castor支持的类型简称列表如下:
简称
原始类型
Java类型
other
N
java.lang.Object
string
N
java.lang.String
integer
Y
java.lang.Integer
long
Y
java.lang.Long
boolean
Y
java.lang.Boolean
double
Y
java.lang.Double
float
Y
java.lang.Float
big-decimal
N
java.math.BigDecimal
byte
Y
java.lang.byte.Type
date
N
java.util.Date
short
Y
java.lang.short.Type
char
Y
java.lang.Character.Type
bytes
N
bytes[]
chars
N
char[]
strings
N
string[]
loacle
N
java.util.Locale
Castor会自动将XML文档中的节点内容自动转换为上述Java对象类型。如果设定了”collection”属性,collection属性值遵从下面的对象对象列表:
简称
原始类型
Java类型
array
<java类型>[]
<java类型>[]
arraylist
java.util.List
java.util.Arraylist
vector
java.util.Vector
java.util.Vector
hashtable
java.util.Hashtable
java.util.Hashtable
collection
java.util.Collection
java.util.Arraylist
set
java.util.Set
java.util.Hashset
map
java.util.Map
java.util.Hashmap
sortedset
java.util.SortedSet
java.util.TreeSet
Collection集合中的对象为Java类型。对于Hashtable和Map类型的对象,Castor同时存储其键和值。对于其映射,可以使用org.exolab.castor.mapping.MapItem类通过顶层(相对于嵌套类映射)类映射定义和嵌套类映射定义来描述。
  • 检查<field>节点中的“签名”属性(”direct”,”set-method”和”get-method”
如果”direct”属性设定为true,则在Java类定义中,该字段必须具有如下的声明:
public <type> <name>;
如果”direct”属性设定为false或者该属性被忽略,Castor会通过该属性的存取方法访问该属性。首先,若设定了'get-method' 'set-method'Castor会访问如下方法签名:
public <type> <get-method>();
 
public void <set-method>(<type> value);
若没有设定'get-method' 'set-method'属性,Castor会尝试访问如下签名方法:
public <type> get<capitalized-name>();
public void set<capitalized-name>(<type> value);
<capitalized-name>是指Castor检查<name>属性值,将其首字母转换为大写,其他字符保持不变。
  • collection字段属性处理的例外情况
在默认情况下,’get-method’属性返回集合字段实例,’set-method’属性设定集合字段实例。特例情况如下表所示:
'get-method'
If a 'get-method' is provided for a collection field, Castor - in adition to the default behaviour described above - will deviate from the standard case for the following special prefixes:
public Iterator iterate...();
A 'get-method' starting with the prefix 'iterate' is treated as Iterator method for the given collection field.
public Enumeration enum...();
A 'get-method' starting with 'enum' is treated as Enumeration method for the given collection field.
'set-method'
If 'set-method' is provided for a collection field, Castor - in addition to the default behaviour described above - will accept an 'add' prefix and expect the following signature:
public void add...(<type> value);
This method is called for each collection element while unmarshalling.
3.4.1 <field>节点的属性
<field>节点可以包含将Java字段映射为XML元素,数据库表列名称等信息。<field>节点可配置的属性如下:
Øname: 该属性是必须的,即使在该映射类中没有该字段属性。如果配置了”direct”属性,”name”属性值必须是映射对象中的一个public字段(该字段必须是public,非static和非transient的类型)。如果没有”direct”和”get-/set-method”属性设定,“name”属性值对应的字段通过该值确定其访问方法(采用Java Bean规范)。
Øtype: 该字段属性的Java类型。Castor使用该信息将XML信息转换为Java对象信息(如将字符串转换为整型),定义该字段访问方法的签名。如果设定了”collection”属性,该属性信息用于指定集合中对象的类型信息。
Ørequired: 在编组和解编过程中,该字段是否可选,默认值为false。
Øtransient: 如果设定为”true”,该字段在处理过程中将被忽略。
Ødirect: 如果为true,该字段在Java类定义中必须是public类型。
Øcollection: 如果该字段存在多个,则Castor使用该属性的设定来处理他们。该类型用于定义对应Java类中集合的类型。
Øget-method: 可选配置,”name”属性对应Java类字段的访问方法,具体使用参考前文描述。
Øset-method: 可选配置,”name”属性对应Java类字段的访问方法,具体使用参考前文描述。
Øcreate-method: 工厂方法,用于构建FieldHandler实例。
3.4.2 <field>节点的子节点
在XML Mapping中,<field>节点的子节点仅包含一个<xml>节点,用于描述如何将该字段属性映射到XML文档元素。
Castor自0.9.5版本以后,支持将一个<field>节点映射为该字段所属Java类构造函数的参数,这种机制通过”set-method”属性来实现。如果需要设定一个字段作为该类对象初始化时构造函数的一个参数,可以设定该字段在Mapping文件中<field>节点的”set-method”属性为”1%”-“9%”。 ”1%”表示构造函数的第一个参数,依次类推。这种机制举例如下:
假定存在如下所示的Java类Foo,Foo类除了具有一个默认的构造函数外,还有一个具有参数的构造函数。
public class Foo {
 private int size = 20;
 public Foo() { }
 public Foo(int size) {
 this.size = size;
 }
 public int getSize() {
 return size;
 }
 public void setSize(int size) {
 this.size = size;
 }
}
如果用户希望在实例化Foo类时,调用Foo类具有参数的构造函数而不是默认无参构造函数,则通过设定如下的映射文件实现。
<?xml version="1.0"?>
<mapping>
<class name="Foo">
 <field name="size" get-method="getSize" set-method="%1" type="int">
 <bind-xml node="attribute"/>
 </field>
</class>
</mapping>
Mapping文件中的setMethod=”1%”的设定,会告诉Castor在实例化Foo类时,使用size属性字段作为构造Foo(int)的参数。
注意:如果设定了 ”set-method”属性,则”get-method”属性也必须设定
3.5<bind-xml>节点定义
<bind-xml>节点的用于描述Java字段如何在XML文档中映射展现。在编组和解编过程中均要使用。
<bind-xml>节点的Schema定义如下:
<xsd:element name="bind-xml">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="class" minOccurs="0"/>
<xsd:element name="property" type="propertyType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:QName" use="optional">
</xsd:attribute>
<xsd:attribute name="type" type="xsd:NMTOKEN" use="optional"/>
<xsd:attribute name="auto-naming" use="optional">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="deriveByClass"/>
<xsd:enumeration value="deriveByField"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="location" type="xsd:string" use="optional">
</xsd:attribute>
<xsd:attribute name="matches" type="xsd:string" use="optional"/>
<xsd:attribute name="reference" type="xsd:boolean" use="optional"/>
<xsd:attribute name="node" use="optional">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="attribute"/>
<xsd:enumeration value="element"/>
<xsd:enumeration value="namespace"/>
<xsd:enumeration value="text"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="QName-prefix" type="xsd:NMTOKEN" use="optional"/>
<xsd:attribute name="transient" type="xsd:boolean" use="optional"/>
</xsd:complexType>
</xsd:element>
3.5.1 <bind-xml>节点的属性
Øname: XML节点或属性的名称。注意:该属性值必须是QName,可以使用名称空间前缀来表明该节点或属性所属的特定名称空间,该前缀在编组过程中并不保留或使用,只是用来保持文档的格式良好。
Øauto-naming: 如果未设定name属性,auto-naming属性用于提示是否Castor自动为该字段构建相应的名称。通常情况下,使用<field>节点中的name属性值作为XML元素的名称。
Øtype: 该节点在XML文档中的 Schema类型,Castor编组框架使用该属性确定对XML节点的处理方式。如”QName”。
Ølocation: 允许用户设定XML文档中 “间接路经”上的节点作为该Java字段属性的映射(如该字段所属类的XML节点映射为“AAA”,该节点的名称为“TTT”,但不是“AAA节点的子节点”,而是“AAA”节点的子节点“BBB”节点的子节点,则可以使用location属性映射为XML文档中的“AAA/BBB/TTT”。详细信息参看下述Loaction属性简介”
ØQName-prefix: 如果该字段对应XML文档节点中的一个QName值,则可以使用该属性设定其前缀。详细信息参考“Castor源代码自动生成章节”。
Øreference: 在解编该字段时,指明该字段是否看作一个对象引用。
Ømatches: 允许覆盖节点名称的匹配规则。该属性值是一个标准的正则表达式,用于替代”name”属性。如果值为”*”,则可以匹配任何XML节点名称,但是仅当不存在其他字段与XML节点名称匹配时,使用该匹配。
Ønode: 表明该字段映射成为XML文档中的属性,节点还是文本元素。默认情况下,原始类型的字段映射成XML属性,其他的映射成为XML节点。
Øtransient: 如果其值设定为true,则视该节点为临时的,不做处理。默认继承<field>节点中transient属性值。
3.5.2 <bind-xml>中使用嵌套的类映射
Castor自0.9.5.3版本开始,<bind-xml>节点支持嵌套的类映射定义。该功能在某个类映射信息需要在多个地方指定时非常方便,如映射Hashtable/HashMap/Map等集合类时的情况。具体使用参考下面的例子:
嵌套类举例
<bind-xml ...>
 <class name="org.exolab.castor.mapping.MapItem">
 <field name="key" type="java.lang.String">
 <bind-xml name="id"/>
 </field>
 <field name="value" type="com.acme.Foo"/>
 </class>
</bind-xml>
3.5.3 location属性简介
<bind-xml>节点中的location属性允许用户将字段映射为XML文档中的内嵌节点或者在映射节点封装一个节点。封装节点只出现在XML文档结构中,与Mapping文件定义的Java对象没有直接映射关系。下面仍以Foo类为例,
 public class Foo {
 private Bar bar = null;
 public Foo();

                        
 public getBar() {
 return bar;
 }
 public void setBar(Bar bar) {
 this.bar = bar;
 }
}
我们希望将该类映射成为下面所示的XML文档(注:’abc’节点并不存在于Foo或者Bar类的定义中)
<?xml version="1.0"?>
<foo>;
 <abc>
 <bar>...</bar>
 </abc>
</foo>
为实现上述映射,我们以如下方式定义Mapping文件
<?xml version="1.0"?>
 ...
 <class name="Foo">
 <field name="bar" type="Bar">
 <bind-xml name="bar" location="abc"/>
 </field>
</class>
 ...
</mapping>
需要注意的是,“location”属性的值指定的是封装的节点的名称,如果希望封装多层节点,则节点名称之间使用”/”分隔,如下例所示:
<bind-xml name="bar" location="abc/xyz" />
此外,用户还需要注意的是,<bind-xml>节点中的属性”name”指定的xml元素名称并不是“location”属性中指定的封装节点的一部分。同时,封装节点的父节点总是其所封装字段所在类对象映射的节点。“location”属性同样可以封装XML属性元素,如下所示的映射定义:
<bind-xml name="bar" location="abc" node="attribute" />
生成的XML文档为:
<?xml version="1.0"?>
<foo>
 <abc bar="..."/>;
</foo>
4. 映射文件使用举例
下面我们以一个完整的例子,说明如何使用Castor的Mapping映射文件实现Java类与XML文档之间的相互转换。
首先,我们定义一个名为”order.xml”的数据文件,我们用这个XML文件描述一个订单,该订单中包含这个订单的客户信息,以及客户在此订单中所订购的货物。一个订单中可以存在多个货物。
order.xml
<?xml version="1.0"?>
<Order reference="12343-AHSHE-314159">
<Client>
<Name>Jean Smith</Name>
<Address>2000, Alameda de las Pulgas, San Mateo, CA 94403</Address>
</Client>
<Item reference="RF-0001">
<Description>Stuffed Penguin</Description>
<Quantity>10</Quantity>
<UnitPrice>8.95</UnitPrice>
</Item>
<Item reference="RF-0034">
<Description>Chocolate</Description>
<Quantity>5</Quantity>
<UnitPrice>28.50</UnitPrice>
</Item>
<Item reference="RF-3341">
<Description>Cookie</Description>
<Quantity>30</Quantity>
<UnitPrice>0.85</UnitPrice>
</Item>
我们要为该订单定义三个Java类,分别描述该订单,订单的客户和货物。
ØMyOrder代表该订单
ØClientData代表订单的客户
ØItem代表订单中的一项货物
这三个Java类的代码如下所示:
MyOrder.java
import java.util.Vector;
import java.util.Enumeration;
publicclass MyOrder {
private String _ref;
private ClientData _client;
private Vector _items;
privatefloat_total;
publicvoid setReference(String ref) {
_ref = ref;
}
public String getReference() {
return_ref;
}
publicvoid setClientData(ClientData client) {
_client = client;
}
public ClientData getClientData() {
return _client;
}
publicvoid setItemsList(Vector items) {
_items = items;
}
public Vector getItemsList() {
return_items;
}
publicvoid setTotal(float total) {
_total = total;
}
publicfloat getTotal() {
return_total;
}
// Do some processing on the data
publicfloat getTotalPrice() {
float total = 0.0f;
for (Enumeration e = _items.elements(); e.hasMoreElements();) {
Item item = (Item) e.nextElement();
total += item._quantity * item._unitPrice;
}
return total;
}
}
ClientData.java
publicclass ClientData {
private String _name;
private String _address;
publicvoid setName(String name) {
_name = name;
}
public String getName() {
return_name;
}
publicvoid setAddress(String address) {
_address = address;
}
public String getAddress() {
return_address;
}
}
Item.java
publicclass Item {
public String _reference;
publicint_quantity;
publicfloat_unitPrice;
public String _description;
}
现在,我们有了预期的XML文档定义,也有了描述文档的Java类定义。下一步,我们定义XML文档与Java类之间的映射。在下面的mapping.xml文件中,我们定义了三个类MyOrder、ClientData和Item的映射。
mapping.xml
<?xml version="1.0"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
"http://castor.org/mapping.dtd">
<mapping>
<class name="MyOrder">
<map-to xml="Order"/>
<field name="Reference" type="java.lang.String">
<bind-xml name="reference" node="attribute"/>
</field>
<field name="Total" type="float">
<bind-xml name="total-price" node="attribute"/>
</field>
<field name="ClientData" type="ClientData">
<bind-xml name="Client"/>
</field>
<field name="ItemsList" type="Item" collection="vector">
<bind-xml name="Item"/>
</field>
</class>
<class name="ClientData">
<field name="Name" type="java.lang.String">
<bind-xml name="Name" node="element"/>
</field>
<field name="Address" type="java.lang.String">
<bind-xml name="Address" node="element"/>
</field>
</class>
<class name="Item">
<field name="_reference" type="java.lang.String" direct="true">
<bind-xml name="reference" node="attribute"/>
</field>
<field name="_quantity" type="integer" direct="true">
<bind-xml name="Quantity" node="element"/>
</field>
<field name="_unitPrice" type="float" direct="true">
<bind-xml name="UnitPrice" node="element"/>
</field>
<field name="_description" type="string" direct="true">
<bind-xml name="Description" node="element"/>
</field>
</class>
</mapping>
具备上述资源后,我们通过下面的Java代码测试Castor通过Mapping映射文件来实现XML文档与Java对象间的相互转换。
main.java
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.Marshaller;
import java.io.FileReader;
import java.io.OutputStreamWriter;
import org.xml.sax.InputSource;
publicclass Main {
publicstaticvoid main(String args[]) {
Mapping mapping = new Mapping();
try {
// 1. Mapping.xml文件中加载映射信息
mapping.loadMapping("mapping.xml");
// 2. 解编order.xml文档,构造java对象
Unmarshaller unmar = new Unmarshaller(mapping);
MyOrder order = (MyOrder) unmar.unmarshal(new InputSource(
new FileReader("order.xml")));
// 3. 调用JavaMyOrder的对象实例方法,修改该对象实例
float total = order.getTotalPrice();
System.out.println("Order total price = " + total);
order.setTotal(total);
// 4. 将修改后的对象实例重新编组为XML文档并输出到控制台
Marshaller marshaller = new Marshaller(new OutputStreamWriter(
System.out));
marshaller.setMapping(mapping);
marshaller.marshal(order);
} catch (Exception e) {
System.out.println(e);
return;
}
}
}
用户可以比较原来的order.xml文档与输出到控制台的XML文档数据的差别,从而体会Castor XML编组框架的功能。
分享到:
评论

相关推荐

    Castor (二) -- 自定义映射

    总之,“Castor(二)-- 自定义映射”这一主题涵盖了如何通过`mapping.dtd`和`mapping.xsd`文件自定义XML和Java对象之间的映射关系,从而更好地适应项目需求。通过熟练运用这些技巧,开发人员可以更加灵活地控制数据...

    castor解析xml与xsd校验xml

    Castor是一个Java库,它提供了一种方便的方式来映射XML数据到Java对象,反之亦然。这个工具在处理XML文档时特别有用,因为它允许开发者通过简单的对象操作来处理复杂的XML结构,而无需直接处理XML语法。本文将深入...

    Castor应用示例代码-1

    这个"Castor应用示例代码-1"是针对《Castor功能与应用参考(二)》一文中的实践部分,用于深入理解Castor的XML编组框架。 首先,让我们来理解Castor的核心功能。Castor的主要特性包括: 1. **XML到Java对象的映射**...

    Castor的使用,如何将java object转换为xml

    Castor是一个开源的数据绑定框架,它允许Java开发者在Java对象和XML之间进行无缝...在实际项目中,根据具体需求选择合适的映射策略和优化手段,可以充分利用Castor的功能,实现灵活且高效的Java对象与XML之间的转换。

    castor1.4 xsd生成java

    7. **替代方案**:随着技术的发展,如JAXB(Java Architecture for XML Binding)和XStream等工具也提供了类似的功能,它们可能更适合处理现代的XML映射需求。 8. **最佳实践**:在使用Castor时,建议保持XSD文件的...

    castor :Java与xml互转示例---代码

    创建Java对象和XML映射文件 在使用Castor之前,通常需要创建一个映射文件(`.xml`格式),它定义了Java类和XML元素之间的对应关系。例如,假设有一个简单的`Person`类: ```java public class Person { private ...

    castor1.3 完整jar包

    总的来说,Castor是一个功能全面的数据绑定工具,它简化了Java应用与XML、数据库和目录服务之间的交互。这个"castor1.3 完整jar包"为开发者提供了一个集成的环境,可以直接将Castor整合到项目中,以提高开发效率并...

    castor 框架jar包和src

    - **配置映射文件**:创建XML映射文件(*.xml),定义XML结构和对应的Java类。 - **导入jar包**:将必要的Castor jar包添加到项目的类路径中。 - **实例化Marshaller和Unmarshaller**:用于XML到Java对象的转换和...

    castor1-2(java and xml 数据绑定过程所需数据包)

    Castor是Java中一个强大的数据绑定框架,它允许开发者将XML文档与Java对象之间进行映射,从而实现XML数据的序列化和反序列化。在Java应用开发中,处理XML数据时,通常需要将XML文件内容转换为Java对象,或者将Java...

    castor-1.2解析XML

    是个不错的XML解析工具。 1、xml格式文件的用法,我们学过的xml有两种用法:一,作为配置文件。二、作为数据存储文件。...2、这个工具的功能:能够把xml文件存储的数据和pojo对象进行映射。我们暂且把这种叫做:OXM。

    解决Castor使用时根节点问题

    3. **使用Castor Mapping**:在Castor中,你需要通过XML映射文件(通常是`.xml`扩展名)来指定Java类和XML元素之间的对应关系。在这个映射文件中,定义根节点与Java顶级类的对应,并为其他类和元素设定映射规则。 4...

    Java 对象XML解析器castor-0.9

    要实现的是O/R映射功能。它主要API和数据接口为:JDO-like, SQL, OQL, JDBC, LDAP, XML, DSML。它支持分布式目录事务处理和时间;提供处理XML、Directory、XADirectory的类库,提供从XML到JAVA类的转换机制。

    javabean 转换 xml映射文件工具

    总的来说,JavaBean到XML映射文件工具是一个提高开发效率的实用工具,它简化了数据在Java对象和XML文档之间的转换,特别是在与Castor框架集成时。理解这个工具的工作原理和使用方法对于任何需要处理数据序列化的Java...

    castor-1.3.2.zip

    5. **灵活的映射**:Castor提供了多种映射选项,比如一对一、一对多、多对一和多对多的关系映射,以及自定义转换函数,使开发者能够根据需求定制XML-Java转换。 6. **性能优化**:Castor通过缓存映射信息和利用内存...

    castor R/M映射神器

    Castor是ExoLab Group下面的一个开放源代码的项目,它主要实现的是O/R映射功能。它主要API和数据接口为:JDO-like, SQL, OQL, JDBC, LDAP, XML, DSML。它支持分布式目录事务处理和时间;提供处理XML、Directory、...

    castor插件java对象和XML自动绑定maping文件生成和java对象一键生成工具

    Castor是一款强大的Java库,它提供了Java对象到XML数据的自动转换功能,反之亦然。这个插件的主要目的是简化XML处理,特别是在Java应用程序中。它通过创建映射文件(Mapping Files)来定义Java对象和XML元素之间的...

    xml与java对象映射

    - **Castor**:Castor提供了XML到Java对象的映射,支持复杂的数据结构,包括集合和嵌套对象。 - **XML Beans**:XML Beans是由Apache组织提供的,它允许开发者通过Java类型系统直接访问XML内容,同时支持XML ...

    castor详解及源代码

    - **对象-XML映射(OXM)**:Castor提供了一种声明式的机制,通过XML映射文件定义Java类和XML元素之间的对应关系。 - **数据绑定**:可以将Java对象直接转换为XML文档,反之也可以将XML解析为Java对象,简化了数据...

    castor-0.9.9.zip

    在XML序列化方面,Castor提供了一种声明性的方式,通过XML映射文件(Mapping File)来定义Java类和XML元素之间的对应关系。开发者可以指定哪些字段或属性应该被序列化到XML,以及它们如何在XML结构中表示。例如,一...

    castor插件java对象和XML自动绑定maping文件生成和java对象一键生成工具1.2

    "castor插件java对象和XML自动绑定mapping文件生成"是Castor的核心功能之一。映射文件(mapping file)是描述Java类和XML元素之间对应关系的配置文件,通常以.xml扩展名。通过这个映射文件,Castor可以知道如何在...

Global site tag (gtag.js) - Google Analytics