Castor是一个java object的OR Mapping工具,可以将java objects保存于database、xml文件和LDAP数据库中(目前版本好像LDAP支持有问题)。下面简单介绍一下怎样用Castor来操纵XML文件 1. 一 最简单的XML文件的操纵 1. 1 读取XML文件 有一个xml文件如下,表示了一个人的信息 person.xml <?xml version="1.0"?> <person> <name>Bob Harris</name> <ssn>222-222-2222</ssn> <address>123 Foo Street</address> <work-phone>(123) 123-1234</work-phone> <home-phone>(123) 123-1234</home-phone> <email>bob@harris.org</email> </person> 对应的java文件 /* * Person.java * */ /** * * @author yj */ import java.io.*; public class Person { private String name; private String address; private String ssn; private String email; private String homePhone; private String workPhone; // -- allows us to create a Person via the constructor public Person(String name, String address, String ssn, String email, String homePhone, String workPhone) { this.name = name; this.address = address; this.ssn = ssn; this.email = email; this.homePhone = homePhone; this.workPhone = workPhone; } // -- used by the data-binding framework public Person() { } // -- accessors public String getName() { return name; } public String getAddress() { return address; } public String getSsn() { return ssn; } public String getEmail() { return email; } public String getHomePhone() { return homePhone; } public String getWorkPhone() { return workPhone; } // -- mutators public void setName(String name) { this.name = name; } public void setAddress(String address) { this.address = address; } public void setSsn(String ssn) { this.ssn = ssn; } public void setEmail(String email) { this.email = email; } public void setHomePhone(String homePhone) { this.homePhone = homePhone; } public void setWorkPhone(String workPhone) { this.workPhone = workPhone; }
} 这是一个读取person.xml文件的例子 /* * ReadPerson.java * */ /** * * @author yj */ import org.exolab.castor.xml.*; import java.io.FileReader; public class ReadPerson { public static void main(String args[]) { try { Person person = (Person) Unmarshaller.unmarshal(Person.class, new FileReader("person.xml")); System.out.println("Person Attributes"); System.out.println("-----------------"); System.out.println("Name: " + person.getName() ); System.out.println("Address: " + person.getAddress() ); System.out.println("SSN: " + person.getSsn() ); System.out.println("Email: " + person.getEmail() ); System.out.println("Home Phone: " + person.getHomePhone() ); System.out.println("Work Phone: " + person.getWorkPhone() ); } catch (Exception e) { System.out.println( e ); } } }
传统上,如果需要操纵XML文件,需要用SAX或者DOM来处理,比较繁琐,有了Castor提供的marshalling and unmarshalling功能,就可以方便的在xml和java object之间方便的映射了。 2. 2 生成XML文件 下面是生成XML文件的例子: /* * CreatPerson.java *
*/ /** * * @author yj */ import org.exolab.castor.xml.*; import java.io.FileWriter; public class CreatePerson { public static void main(String args[]) { try { // -- create a person to work with Person person = new Person("Bob Harris", "123 Foo Street", "222-222-2222", "bob@harris.org", "(123) 123-1234", "(123) 123-1234"); // -- marshal the person object out as a <person> FileWriter file = new FileWriter("bob_person.xml"); Marshaller.marshal(person, file); file.close(); } catch (Exception e) { System.out.println( e); } } }
这是上面的CreatePerson生成的xml文件 bob_person.xml <?xml version="1.0"?> <person><ssn>222-222-2222</ssn><address>123 Foo Street</address><work-phone>(123) 123-1234</work-phone><home-phone>(123) 123-1234</home-phone><email>bob@harris.org</email><name>Bob Harris</name></person> 3. 3 修改现有的XML文件 修改现有的XML文件也很简单 /* * ModifyPerson.java * */ /** * * @author yj */ import org.exolab.castor.xml.*; import java.io.FileWriter; import java.io.FileReader; public class ModifyPerson { public static void main(String args[]) { try { // -- read in the person Person person = (Person) Unmarshaller.unmarshal(Person.class, new FileReader("person.xml")); // -- change the name person.setName("David Beckham"); person.setEmail("David@beckham.com"); // -- marshal the changed person back to disk FileWriter file = new FileWriter("person.xml"); Marshaller.marshal(person, file); file.close(); } catch (Exception e) { System.out.println( e ); } } } 2. 二 复杂XML文件的操纵 这个例子演示了如果操纵复杂的xml文件 文件addressbook.xml如下 <?xml version="1.0"?> <addressbook name="Manchester United Address Book"> <person name="Roy Keane"> <address>23 Whistlestop Ave</address> <ssn>111-222-3333</ssn> <email>roykeane@manutd.com</email> <home-phone>720.111.2222</home-phone> <work-phone>111.222.3333</work-phone> </person> <person name="Juan Sebastian Veron"> <address>123 Foobar Lane</address> <ssn>222-333-444</ssn> <email>juanveron@manutd.com</email> <home-phone>720.111.2222</home-phone> <work-phone>111.222.3333</work-phone> </person> <person name ="Bob Harris"> <ssn>222-222-2222</ssn> <address>123 Foo Street</address> <work-phone>(123) 123-1234</work-phone> <home-phone>(123) 123-1234</home-phone> <email>bob@harris.org</email> </person> </addressbook> 可以看到,addressbook包含多条记录,每条记录是一个通讯录。为了对应复杂的xml文件,需要一个mapping.xml文件,来说明xml文件的项目和java object的对应关系 <?xml version="1.0"?> <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN" "http://castor.exolab.org/mapping.dtd"> <mapping> <description>A mapping file for our Address Book application</description> <class name="Person"> <field name="name" type="string"> <bind-xml name="name" node="attribute" /> </field> <field name="address" type="string" /> <field name="ssn" type="string" /> <field name="email" type="string" /> <field name="homePhone" type="string" /> <field name="workPhone" type="string" /> </class> <class name="Addressbook"> <field name="name" type="string"> <bind-xml name="name" node="attribute" /> </field> <field name="persons" type="Person" collection="collection" /> </class> </mapping> §这样,就可以一样很方便的使用Castor来操纵这个XML文件了 同样,需要一个java文件来对应addressbook import java.util.List; import java.util.ArrayList; public class Addressbook { private String addressBookName; private List persons = new ArrayList(); public Addressbook() { } // -- manipulate the List of Person objects public void addPerson(Person person) { persons.add(person); } public List getPersons() { return persons; } // -- manipulate the name of the address book public String getName() { return addressBookName; } public void setName(String name) { this.addressBookName = name; } } 察看addressbook的java 代码 import org.exolab.castor.xml.*; import org.exolab.castor.mapping.*; import java.io.FileReader; import java.util.List; import java.util.Iterator; public class ViewAddressbook { public static void main(String args[]) { try { // -- Load a mapping file Mapping mapping = new Mapping(); mapping.loadMapping("mapping.xml"); Unmarshaller un = new Unmarshaller(Addressbook.class); un.setMapping( mapping ); // -- Read in the Addressbook using the mapping FileReader in = new FileReader("addressbook.xml"); Addressbook book = (Addressbook) un.unmarshal(in); in.close(); // -- Display the addressbook System.out.println( book.getName() ); List persons = book.getPersons(); Iterator iter = persons.iterator(); while ( iter.hasNext() ) { Person person = (Person) iter.next(); System.out.println("\n" + person.getName() ); System.out.println("-----------------------------"); System.out.println("Address = "+ person.getAddress()); System.out.println("SSN = " + person.getSsn() ); System.out.println("Home Phone = " + person.getHomePhone() ); System.out.println("email = " + person.getEmail() ); } } catch (Exception e) { System.out.println( e ); } } }
再看另外一个例子: 缺省用法: 缺省用法指的是没有使用映射格式描述文件时的用法
import java.io.*; import org.exolab.castor.xml.*; public class Test{
public static void main(String[] argv) {
// build a test bean FlightBean bean = new FlightBean(); bean.setCarrier("AR"); bean.setNumber(426); bean.setDepartureTime("6:23a"); bean.setArrivalTime("8:42a");
try { // write it out as XML File file = new File("test.xml"); Writer writer = new FileWriter(file); Marshaller.marshal(bean, writer); // now restore the value and list what we get Reader reader = new FileReader(file); FlightBean read = (FlightBean)Unmarshaller.unmarshal(FlightBean.class, reader); System.out.println("Flight "+read.getCarrier()+read.getNumber() + " departing at " + read.getDepartureTime() +" and arriving at " + read.getArrivalTime()); } catch (IOException ex) { ex.printStackTrace(System.err); } catch (MarshalException ex) { ex.printStackTrace(System.err); } catch (ValidationException ex) { ex.printStackTrace(System.err); }
}
}
程序运行结果: D:\java>count.bat (这个文件请下载我的,设置classpath)
D:\java>set CLASSPATH=d:\java\jar\xercesImpl.jar;d:\java\jar\castor-0.9.5.3-xml. jar;;d:\jdk1.5\lib;d:\java
D:\java>javac FlightBean.java(这个文件请下载我的)
D:\java>javac Test.java
D:\java>java Test Flight AR426 departing at 6:23a and arriving at 8:42a
缺省用法生成的XML文件test.xml如下: <?xml version="1.0" encoding="UTF-8"?> <flight-bean number="426"> <arrival-time>8:42a</arrival-time> <departure-time>6:23a</departure-time> <carrier>AR</carrier> </flight-bean> 也就是说: 对FlightBena中具有基本类型值的属性创建元素的一个属性(本例中只有number属性通过 getNumber()方法公开为int值)。 对于每个具有对象类型值的属性创建根元素的一个子元素(本例中的所有其他属性,因为它们是字符串)。
标准用法:
import java.io.*; import org.exolab.castor.xml.*; import org.exolab.castor.mapping.*;
public class Test1{
public static void main(String[] argv) {
// build a test bean FlightBean bean = new FlightBean(); bean.setCarrier("AR"); bean.setNumber(426); bean.setDepartureTime("6:23a"); bean.setArrivalTime("8:42a"); try { // write it out as XML Mapping map=new Mapping(); map.loadMapping("mapping.xml");
File file = new File("test1.xml"); Writer writer = new FileWriter(file); Marshaller marshaller =new Marshaller(writer); marshaller.setMapping(map); marshaller.marshal(bean);
// now restore the value and list what we get Reader reader = new FileReader(file); Unmarshaller unmarshaller = new Unmarshaller(map); FlightBean read = (FlightBean)unmarshaller.unmarshal(reader); System.out.println("Flight " + read.getCarrier() + read.getNumber() + " departing at " + read.getDepartureTime() +" and arriving at " + read.getArrivalTime()); } catch (IOException ex) { ex.printStackTrace(System.err); } catch (MarshalException ex) { ex.printStackTrace(System.err); } catch (ValidationException ex) { ex.printStackTrace(System.err); }catch (MappingException ex) { ex.printStackTrace(System.err); }
}
}
程序结果:D:\java>java Test1 Flight AR426 departing at 6:23a and arriving at 8:42a
D:\java>
标准用法生成的XML文件test1.xml如下: <?xml version="1.0" encoding="UTF-8"?> <flight carrier="AR" depart="6:23a" arrive="8:42a" number="426"/> 这一般是我们期望的,只所以生成我们所期望的格式,是因为我们使用了映射格式描述文件mapping.xml。它也是XML文件: <!DOCTYPE databases PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.exolab.org/mapping.dtd"> <mapping> <description>Basic mapping example</description> <class name="FlightBean" auto-complete="ture"> <map-to xml="flight"/> <field name="carrier"> <bind-xml name="carrier" node="attribute"/> </field> <field name="departureTime"> <bind-xml name="depart" node="attribute"/> </field> <field name="arrivalTime"> <bind-xml name="arrive" node="attribute"/> </field> </class> </mapping> 注意 (1) class标签里name应该是带有包名的JavaBean类全名 (2) map-to xml="flight"指XML文件的根节点,区分大小写 (3) auto-complete="false"或没有auto-complete属性时number属性会没有
|
|