众所周知,xml解析一般有SAX和DOM两种方式。

SAX是基于事件驱动的行解析,具有速度快,占用内存小的优点,但是实现麻烦,代码可读性较差。

DOM是基于树状结构的解析,也就是其将整个xml文档看作一棵树,然后按照不同的分支/节点解析,更具面向对象的风格。缺点就是其需要将整个xml读到内存中,所以占用内存较多,而且比较慢。

实际应用中,很多场景是:程序将xml中的数据解析出来后,然后生成一些java对象来保持这些数据。于是需要在代码中频繁调用创建对象、get/set等的代码。

0.下面是一个使用DOM解析文档的例子。

Address.java

[java] view plain copy print ?
  1. /**
  2. *
  3. */
  4. package com.hayden.model;
  5. /**
  6. * @author HaydenWang
  7. *
  8. */
  9. public class Address implements java.io.Serializable {
  10. private static final long serialVersionUID = 1863183127959586043L;
  11. private Long id;
  12. private String detail;
  13. public Long getId() {
  14. return id;
  15. }
  16. public void setId(Long id) {
  17. this.id = id;
  18. }
  19. public String getDetail() {
  20. return detail;
  21. }
  22. public void setDetail(String detail) {
  23. this.detail = detail;
  24. }
  25. @Override
  26. public String toString() {
  27. return "Address [detail=" + detail + ", id=" + id + "]";
  28. }
  29. @Override
  30. public int hashCode() {
  31. final int prime = 31;
  32. int result = 1;
  33. result = prime * result + ((detail == null) ? 0 : detail.hashCode());
  34. result = prime * result + ((id == null) ? 0 : id.hashCode());
  35. return result;
  36. }
  37. @Override
  38. public boolean equals(Object obj) {
  39. if (this == obj)
  40. return true;
  41. if (obj == null)
  42. return false;
  43. if (getClass() != obj.getClass())
  44. return false;
  45. Address other = (Address) obj;
  46. if (detail == null) {
  47. if (other.detail != null)
  48. return false;
  49. } else if (!detail.equals(other.detail))
  50. return false;
  51. if (id == null) {
  52. if (other.id != null)
  53. return false;
  54. } else if (!id.equals(other.id))
  55. return false;
  56. return true;
  57. }
  58. }

/** * */ package com.hayden.model; /** * @author HaydenWang * */ public class Address implements java.io.Serializable { private static final long serialVersionUID = 1863183127959586043L; private Long id; private String detail; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } @Override public String toString() { return "Address [detail=" + detail + ", id=" + id + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((detail == null) ? 0 : detail.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Address other = (Address) obj; if (detail == null) { if (other.detail != null) return false; } else if (!detail.equals(other.detail)) return false; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } }

User.java

[java] view plain copy print ?
  1. /**
  2. *
  3. */
  4. package com.hayden.model;
  5. import java.util.Date;
  6. /**
  7. * @author HaydenWang
  8. *
  9. */
  10. public class User {
  11. private Long id;
  12. private String name;
  13. private Address address;
  14. private Date createDate;
  15. public Long getId() {
  16. return id;
  17. }
  18. public void setId(Long id) {
  19. this.id = id;
  20. }
  21. public String getName() {
  22. return name;
  23. }
  24. public void setName(String name) {
  25. this.name = name;
  26. }
  27. public Address getAddress() {
  28. return address;
  29. }
  30. public void setAddress(Address address) {
  31. this.address = address;
  32. }
  33. public Date getCreateDate() {
  34. return createDate;
  35. }
  36. public void setCreateDate(Date createDate) {
  37. this.createDate = createDate;
  38. }
  39. @Override
  40. public int hashCode() {
  41. final int prime = 31;
  42. int result = 1;
  43. result = prime * result + ((address == null) ? 0 : address.hashCode());
  44. result = prime * result
  45. + ((createDate == null) ? 0 : createDate.hashCode());
  46. result = prime * result + ((id == null) ? 0 : id.hashCode());
  47. result = prime * result + ((name == null) ? 0 : name.hashCode());
  48. return result;
  49. }
  50. @Override
  51. public boolean equals(Object obj) {
  52. if (this == obj)
  53. return true;
  54. if (obj == null)
  55. return false;
  56. if (getClass() != obj.getClass())
  57. return false;
  58. User other = (User) obj;
  59. if (address == null) {
  60. if (other.address != null)
  61. return false;
  62. } else if (!address.equals(other.address))
  63. return false;
  64. if (createDate == null) {
  65. if (other.createDate != null)
  66. return false;
  67. } else if (!createDate.equals(other.createDate))
  68. return false;
  69. if (id == null) {
  70. if (other.id != null)
  71. return false;
  72. } else if (!id.equals(other.id))
  73. return false;
  74. if (name == null) {
  75. if (other.name != null)
  76. return false;
  77. } else if (!name.equals(other.name))
  78. return false;
  79. return true;
  80. }
  81. @Override
  82. public String toString() {
  83. return "User [address=" + address + ", createDate=" + createDate
  84. + ", id=" + id + ", name=" + name + "]";
  85. }
  86. }

/** * */ package com.hayden.model; import java.util.Date; /** * @author HaydenWang * */ public class User { private Long id; private String name; private Address address; private Date createDate; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((address == null) ? 0 : address.hashCode()); result = prime * result + ((createDate == null) ? 0 : createDate.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (address == null) { if (other.address != null) return false; } else if (!address.equals(other.address)) return false; if (createDate == null) { if (other.createDate != null) return false; } else if (!createDate.equals(other.createDate)) return false; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "User [address=" + address + ", createDate=" + createDate + ", id=" + id + ", name=" + name + "]"; } }

Domparser.java

[java] view plain copy print ?
  1. /**
  2. *
  3. */
  4. package com.hayden.dom;
  5. import java.text.ParseException;
  6. import java.text.SimpleDateFormat;
  7. import java.util.Date;
  8. import org.apache.log4j.Logger;
  9. import org.w3c.dom.Document;
  10. import org.w3c.dom.Node;
  11. import org.w3c.dom.NodeList;
  12. import com.hayden.castor.XmlUtil;
  13. import com.hayden.model.Address;
  14. import com.hayden.model.User;
  15. /**
  16. * @author HaydenWang
  17. *
  18. */
  19. public class DomParser {
  20. private static final Logger logger = Logger.getLogger(DomParser.class);
  21. private static final String FORMAT = "yyyy-MM-dd";
  22. public User parseUser(String fileName) {
  23. Document doc = XmlUtil.getDocumentFromFile(fileName);
  24. Node node = doc.getFirstChild();
  25. User user = new User();
  26. if ("user".equals(node.getNodeName())) {
  27. NodeList childNodes = node.getChildNodes();
  28. int length = childNodes.getLength();
  29. for (int i = 0; i < length; i++) {
  30. Node subNode = childNodes.item(i);
  31. String nodeName = subNode.getNodeName();
  32. if ("address".equals(nodeName)) {// this is address node
  33. Address addr = parseAddress(subNode);
  34. user.setAddress(addr);
  35. } else if ("name".equals(nodeName)) { // this is name node
  36. String userName = getNodeValue(subNode);
  37. user.setName(userName);
  38. } else if ("id".equals(nodeName)) {
  39. String idString = getNodeValue(subNode);
  40. user.setId(Long.parseLong(idString));
  41. }else if("create-date".equals(nodeName)){
  42. String dateString = getNodeValue(subNode);
  43. Date date = parseDate(dateString);
  44. user.setCreateDate(date);
  45. }
  46. }
  47. }
  48. return user;
  49. }
  50. private Address parseAddress(Node addrNode) {
  51. Address addr = new Address();
  52. NodeList nodeList = addrNode.getChildNodes();
  53. int length = nodeList.getLength();
  54. for (int i = 0; i < length; i++) {
  55. Node node = nodeList.item(i);
  56. String nodeName = node.getNodeName();
  57. if ("id".equals(nodeName)) {
  58. String idString = getNodeValue(node);
  59. addr.setId(Long.parseLong(idString));
  60. } else if ("details".equals(nodeName)) {
  61. addr.setDetail(getNodeValue(node));
  62. }
  63. }
  64. return addr;
  65. }
  66. /**
  67. * get the value for the node with format <name>helen</name>
  68. *
  69. * @param node
  70. * @return
  71. */
  72. private String getNodeValue(Node node) {
  73. String nodeValue = null;
  74. if (null != node) {
  75. NodeList childNodeList = node.getChildNodes();
  76. if (childNodeList != null) {
  77. for (int i = 0, j = childNodeList.getLength(); i < j; i++) {
  78. Node currentNode = childNodeList.item(i);
  79. nodeValue = currentNode.getNodeValue();
  80. break;
  81. }
  82. } else {
  83. logger.debug("The node is empty");
  84. }
  85. logger.debug(" The nodeName: " + node.getNodeName()
  86. + ", and the value: " + nodeValue);
  87. } else {
  88. logger.warn("The node is null, so can't take its value");
  89. }
  90. return nodeValue;
  91. }
  92. private static final Date parseDate(String input){
  93. SimpleDateFormat formatter = new SimpleDateFormat(FORMAT);
  94. Date date = null;
  95. try {
  96. date = formatter.parse((String) input);
  97. } catch (ParseException px) {
  98. throw new IllegalArgumentException(px.getMessage());
  99. }
  100. return date;
  101. }
  102. }

/** * */ package com.hayden.dom; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.hayden.castor.XmlUtil; import com.hayden.model.Address; import com.hayden.model.User; /** * @author HaydenWang * */ public class DomParser { private static final Logger logger = Logger.getLogger(DomParser.class); private static final String FORMAT = "yyyy-MM-dd"; public User parseUser(String fileName) { Document doc = XmlUtil.getDocumentFromFile(fileName); Node node = doc.getFirstChild(); User user = new User(); if ("user".equals(node.getNodeName())) { NodeList childNodes = node.getChildNodes(); int length = childNodes.getLength(); for (int i = 0; i < length; i++) { Node subNode = childNodes.item(i); String nodeName = subNode.getNodeName(); if ("address".equals(nodeName)) {// this is address node Address addr = parseAddress(subNode); user.setAddress(addr); } else if ("name".equals(nodeName)) { // this is name node String userName = getNodeValue(subNode); user.setName(userName); } else if ("id".equals(nodeName)) { String idString = getNodeValue(subNode); user.setId(Long.parseLong(idString)); }else if("create-date".equals(nodeName)){ String dateString = getNodeValue(subNode); Date date = parseDate(dateString); user.setCreateDate(date); } } } return user; } private Address parseAddress(Node addrNode) { Address addr = new Address(); NodeList nodeList = addrNode.getChildNodes(); int length = nodeList.getLength(); for (int i = 0; i < length; i++) { Node node = nodeList.item(i); String nodeName = node.getNodeName(); if ("id".equals(nodeName)) { String idString = getNodeValue(node); addr.setId(Long.parseLong(idString)); } else if ("details".equals(nodeName)) { addr.setDetail(getNodeValue(node)); } } return addr; } /** * get the value for the node with format <name>helen</name> * * @param node * @return */ private String getNodeValue(Node node) { String nodeValue = null; if (null != node) { NodeList childNodeList = node.getChildNodes(); if (childNodeList != null) { for (int i = 0, j = childNodeList.getLength(); i < j; i++) { Node currentNode = childNodeList.item(i); nodeValue = currentNode.getNodeValue(); break; } } else { logger.debug("The node is empty"); } logger.debug(" The nodeName: " + node.getNodeName() + ", and the value: " + nodeValue); } else { logger.warn("The node is null, so can't take its value"); } return nodeValue; } private static final Date parseDate(String input){ SimpleDateFormat formatter = new SimpleDateFormat(FORMAT); Date date = null; try { date = formatter.parse((String) input); } catch (ParseException px) { throw new IllegalArgumentException(px.getMessage()); } return date; } }

通过上面的代码可以看出,有很多重复性的体力活(频繁判断节点的内容,然后set到对象中),而且当我们需要给这些对象增加或者修改一些属性的时候,就需要修改解析xml的程序。

那么是否有工具可以帮助实现这些事情呢?这就是Castor等Xml-Object mapping的工具做的事情。

Castor中有两个核心的操作:

  • marshaller:将对象转换成xml
  • unmarshaller: 从xml中解析并且生成java对象。

下面分别看看Castor在几种不同场景下的使用。

<!--[if !supportLists]-->1. <!--[endif]-->默认情况下,Castor会自动扫描类中的set/get方法,会自动将该属性和xml中的节点对应起来。如果属性不是String类型,在marshaller的时候将调用其toString()方法,同样在unmarshaller的时候,也会自动将其转型到所需类型。下面是一个使用Castor默认配置的例子。

[java] view plain copy print ?
  1. /**
  2. *
  3. */
  4. package com.hayden.castor;
  5. import static org.junit.Assert.fail;
  6. import java.io.FileReader;
  7. import java.io.FileWriter;
  8. import java.util.Date;
  9. import org.exolab.castor.xml.Marshaller;
  10. import org.exolab.castor.xml.Unmarshaller;
  11. import org.junit.Assert;
  12. import org.junit.Before;
  13. import org.junit.Test;
  14. import com.hayden.model.Address;
  15. import com.hayden.model.User;
  16. /**
  17. * @author HaydenWang
  18. *
  19. */
  20. public class SimpletestCastor {
  21. private User user;
  22. @Before
  23. public void init() {
  24. Address addr = new Address();
  25. addr.setId(100l);
  26. addr.setDetail("Baidu Building");
  27. user = new User();
  28. user.setId(1111L);
  29. user.setName("Helen");
  30. user.setAddress(addr);
  31. user.setCreateDate(new Date());
  32. }
  33. @Test
  34. public void simpleTest() {
  35. try {
  36. FileWriter writer = new FileWriter("simpleTest.xml");
  37. Marshaller.marshal(user, writer);
  38. // Create a Reader to the file to unmarshal from
  39. FileReader reader = new FileReader("simpleTest.xml");
  40. // Marshal the user object
  41. User userFromXml = (User) Unmarshaller.unmarshal(User.class, reader);
  42. System.out.println(userFromXml);
  43. Assert.assertEquals(user, userFromXml);
  44. } catch (Exception e) {
  45. e.printStackTrace();
  46. fail(e.getMessage());
  47. }
  48. }
  49. }

/** * */ package com.hayden.castor; import static org.junit.Assert.fail; import java.io.FileReader; import java.io.FileWriter; import java.util.Date; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.hayden.model.Address; import com.hayden.model.User; /** * @author HaydenWang * */ public class SimpletestCastor { private User user; @Before public void init() { Address addr = new Address(); addr.setId(100l); addr.setDetail("Baidu Building"); user = new User(); user.setId(1111L); user.setName("Helen"); user.setAddress(addr); user.setCreateDate(new Date()); } @Test public void simpleTest() { try { FileWriter writer = new FileWriter("simpleTest.xml"); Marshaller.marshal(user, writer); // Create a Reader to the file to unmarshal from FileReader reader = new FileReader("simpleTest.xml"); // Marshal the user object User userFromXml = (User) Unmarshaller.unmarshal(User.class, reader); System.out.println(userFromXml); Assert.assertEquals(user, userFromXml); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } }

<!--[if !supportLists]-->2. <!--[endif]-->当默认的mapping不能满足要求时,比如有的时候我们可能需要去节点的某个属性的值map到对象的属性,有的时候则是将某个节点的值map到对象的属性,这个时候我们就需要自己定义mapping文件。

userMapping.xml

[xhtml] view plain copy print ?
  1. <?xml version="1.0"?>
  2. <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd">
  3. <mapping>
  4. <class name="com.hayden.model.Address">
  5. <map-to xml="address" />
  6. <field name="id" type="java.lang.Long">
  7. <bind-xml name="id" node="element" />
  8. </field>
  9. <field name="detail" type="java.lang.String">
  10. <bind-xml name="detail" node="element" />
  11. </field>
  12. </class>
  13. <class name="com.hayden.model.User">
  14. <map-to xml="user" />
  15. <field name="id" type="java.lang.Long">
  16. <bind-xml name="id" node="element" />
  17. </field>
  18. <field name="name" type="java.lang.String">
  19. <bind-xml name="name" node="element" />
  20. </field>
  21. <field name="address" type="com.hayden.model.Address">
  22. <bind-xml name="address" node="element" />
  23. </field>
  24. <field name="type" type="java.lang.Integer">
  25. <bind-xml name="type" node="element" />
  26. </field>
  27. </class>
  28. </mapping>

<?xml version="1.0"?> <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd"> <mapping> <class name="com.hayden.model.Address"> <map-to xml="address" /> <field name="id" type="java.lang.Long"> <bind-xml name="id" node="element" /> </field> <field name="detail" type="java.lang.String"> <bind-xml name="detail" node="element" /> </field> </class> <class name="com.hayden.model.User"> <map-to xml="user" /> <field name="id" type="java.lang.Long"> <bind-xml name="id" node="element" /> </field> <field name="name" type="java.lang.String"> <bind-xml name="name" node="element" /> </field> <field name="address" type="com.hayden.model.Address"> <bind-xml name="address" node="element" /> </field> <field name="type" type="java.lang.Integer"> <bind-xml name="type" node="element" /> </field> </class> </mapping>

CastorMappingTest.java

[java] view plain copy print ?
  1. /**
  2. *
  3. */
  4. package com.hayden.castor;
  5. import static org.junit.Assert.fail;
  6. import java.io.FileReader;
  7. import java.io.FileWriter;
  8. import org.exolab.castor.mapping.Mapping;
  9. import org.exolab.castor.xml.Marshaller;
  10. import org.exolab.castor.xml.Unmarshaller;
  11. import org.junit.Assert;
  12. import org.junit.Before;
  13. import org.junit.Test;
  14. import com.hayden.model.Address;
  15. import com.hayden.model.User;
  16. /**
  17. * @author HaydenWang
  18. *
  19. */
  20. public class CastorMappingTest {
  21. private User user;
  22. @Before
  23. public void init() {
  24. Address addr = new Address();
  25. addr.setId(100l);
  26. addr.setDetail("Baidu Building");
  27. user = new User();
  28. user.setId(1111L);
  29. user.setName("Helen");
  30. user.setAddress(addr);
  31. user.setType(User.TYPE_COMMON_USER);
  32. }
  33. @Test
  34. public void mappingTest() {
  35. try { // Load Mapping
  36. Mapping mapping = new Mapping();
  37. mapping.loadMapping("file:conf//userMapping.xml");
  38. Marshaller marshaller = new Marshaller();
  39. marshaller.setMapping(mapping);
  40. FileWriter writer = new FileWriter("out//userMappingTest.xml");
  41. marshaller.setWriter(writer);
  42. marshaller.marshal(user);
  43. // Create a Reader to the file to unmarshal from
  44. FileReader reader = new FileReader("out//userMappingTest.xml");
  45. // Create a new Unmarshaller
  46. Unmarshaller unmarshaller = new Unmarshaller(mapping);
  47. unmarshaller.setClass(User.class);
  48. // Unmarshal the user object
  49. User userFromXml = (User) unmarshaller.unmarshal(reader);
  50. System.out.println(userFromXml);
  51. Assert.assertEquals(user, userFromXml);
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. fail(e.getMessage());
  55. }
  56. }
  57. }

/** * */ package com.hayden.castor; import static org.junit.Assert.fail; import java.io.FileReader; import java.io.FileWriter; import org.exolab.castor.mapping.Mapping; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.hayden.model.Address; import com.hayden.model.User; /** * @author HaydenWang * */ public class CastorMappingTest { private User user; @Before public void init() { Address addr = new Address(); addr.setId(100l); addr.setDetail("Baidu Building"); user = new User(); user.setId(1111L); user.setName("Helen"); user.setAddress(addr); user.setType(User.TYPE_COMMON_USER); } @Test public void mappingTest() { try { // Load Mapping Mapping mapping = new Mapping(); mapping.loadMapping("file:conf//userMapping.xml"); Marshaller marshaller = new Marshaller(); marshaller.setMapping(mapping); FileWriter writer = new FileWriter("out//userMappingTest.xml"); marshaller.setWriter(writer); marshaller.marshal(user); // Create a Reader to the file to unmarshal from FileReader reader = new FileReader("out//userMappingTest.xml"); // Create a new Unmarshaller Unmarshaller unmarshaller = new Unmarshaller(mapping); unmarshaller.setClass(User.class); // Unmarshal the user object User userFromXml = (User) unmarshaller.unmarshal(reader); System.out.println(userFromXml); Assert.assertEquals(user, userFromXml); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } }

<!--[if !supportLists]-->3. <!--[endif]-->以上的例子都是直接将xml中的值赋给对象的属性,可是有的时候,我们需要将这些值进行包装。如上面例子中的用户的type属性,在代码中是Long类型,可是我们希望在xml中是有意义的字符,如对于type为1的时候,输出“admin”。对于这种情况,这个时候我们就需要写一些FieldHandler来解决这类问题。

UserTypeHandler.java

[java] view plain copy print ?
  1. package com.hayden.castor;
  2. import org.exolab.castor.mapping.GeneralizedFieldHandler;
  3. import com.hayden.model.User;
  4. public class UserTypeHandler extends GeneralizedFieldHandler {
  5. @Override
  6. public Object convertUponGet(Object value) {
  7. Long type = (Long) value;
  8. if (User.TYPE_ADMIN.equals(type)) {
  9. return "admin";
  10. } else {
  11. return "common user";
  12. }
  13. }
  14. @Override
  15. public Object convertUponSet(Object value) {
  16. String typeString = (String) value;
  17. if ("admin".equals(typeString)) {
  18. return User.TYPE_ADMIN;
  19. } else {
  20. return User.TYPE_COMMON_USER;
  21. }
  22. }
  23. @Override
  24. public Class getFieldType() {
  25. return Long.class;
  26. }
  27. }

package com.hayden.castor; import org.exolab.castor.mapping.GeneralizedFieldHandler; import com.hayden.model.User; public class UserTypeHandler extends GeneralizedFieldHandler { @Override public Object convertUponGet(Object value) { Long type = (Long) value; if (User.TYPE_ADMIN.equals(type)) { return "admin"; } else { return "common user"; } } @Override public Object convertUponSet(Object value) { String typeString = (String) value; if ("admin".equals(typeString)) { return User.TYPE_ADMIN; } else { return User.TYPE_COMMON_USER; } } @Override public Class getFieldType() { return Long.class; } }

fieldHandlerMapping.xml

[java] view plain copy print ?
  1. <?xml version="1.0"?>
  2. <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd">
  3. <mapping>
  4. <class name="com.hayden.model.Address">
  5. <map-to xml="address" />
  6. <field name="id" type="java.lang.Long">
  7. <bind-xml name="id" node="element" />
  8. </field>
  9. <field name="detail" type="java.lang.String">
  10. <bind-xml name="detail" node="element" />
  11. </field>
  12. </class>
  13. <class name="com.hayden.model.User">
  14. <map-to xml="user" />
  15. <field name="id" type="java.lang.Long">
  16. <bind-xml name="id" node="element" />
  17. </field>
  18. <field name="name" type="java.lang.String">
  19. <bind-xml name="name" node="element" />
  20. </field>
  21. <field name="address" type="com.hayden.model.Address">
  22. <bind-xml name="address" node="element" />
  23. </field>
  24. <field name="type" type="java.lang.String" handler="com.hayden.castor.UserTypeHandler">
  25. <bind-xml name="type" node="element" />
  26. </field>
  27. </class>
  28. </mapping>

<?xml version="1.0"?> <!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN" "http://castor.org/mapping.dtd"> <mapping> <class name="com.hayden.model.Address"> <map-to xml="address" /> <field name="id" type="java.lang.Long"> <bind-xml name="id" node="element" /> </field> <field name="detail" type="java.lang.String"> <bind-xml name="detail" node="element" /> </field> </class> <class name="com.hayden.model.User"> <map-to xml="user" /> <field name="id" type="java.lang.Long"> <bind-xml name="id" node="element" /> </field> <field name="name" type="java.lang.String"> <bind-xml name="name" node="element" /> </field> <field name="address" type="com.hayden.model.Address"> <bind-xml name="address" node="element" /> </field> <field name="type" type="java.lang.String" handler="com.hayden.castor.UserTypeHandler"> <bind-xml name="type" node="element" /> </field> </class> </mapping>

FieldHandlerMappingTest.java

[java] view plain copy print ?
  1. /**
  2. *
  3. */
  4. package com.hayden.castor;
  5. import static org.junit.Assert.fail;
  6. import java.io.FileReader;
  7. import java.io.FileWriter;
  8. import org.exolab.castor.mapping.Mapping;
  9. import org.exolab.castor.xml.Marshaller;
  10. import org.exolab.castor.xml.Unmarshaller;
  11. import org.junit.Assert;
  12. import org.junit.Before;
  13. import org.junit.Test;
  14. import com.hayden.model.Address;
  15. import com.hayden.model.User;
  16. /**
  17. * @author HaydenWang
  18. *
  19. */
  20. public class FieldHandlerMappingTest {
  21. private User user;
  22. @Before
  23. public void init() {
  24. Address addr = new Address();
  25. addr.setId(100l);
  26. addr.setDetail("Baidu Building");
  27. user = new User();
  28. user.setId(1111L);
  29. user.setName("Helen");
  30. user.setAddress(addr);
  31. user.setType(User.TYPE_COMMON_USER);
  32. }
  33. @Test
  34. public void mappingTest() {
  35. try { // Load Mapping
  36. Mapping mapping = new Mapping();
  37. mapping.loadMapping("file:conf//fieldHandlerMapping.xml");
  38. Marshaller marshaller = new Marshaller();
  39. marshaller.setMapping(mapping);
  40. FileWriter writer = new FileWriter("out//fieldHandlerTest.xml");
  41. marshaller.setWriter(writer);
  42. marshaller.marshal(user);
  43. // Create a Reader to the file to unmarshal from
  44. FileReader reader = new FileReader("out//fieldHandlerTest.xml");
  45. // Create a new Unmarshaller
  46. Unmarshaller unmarshaller = new Unmarshaller(mapping);
  47. unmarshaller.setClass(User.class);
  48. // Unmarshal the user object
  49. User userFromXml = (User) unmarshaller.unmarshal(reader);
  50. System.out.println(userFromXml);
  51. Assert.assertEquals(user, userFromXml);
  52. } catch (Exception e) {
  53. e.printStackTrace();
  54. fail(e.getMessage());
  55. }
  56. }
  57. }

/** * */ package com.hayden.castor; import static org.junit.Assert.fail; import java.io.FileReader; import java.io.FileWriter; import org.exolab.castor.mapping.Mapping; import org.exolab.castor.xml.Marshaller; import org.exolab.castor.xml.Unmarshaller; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.hayden.model.Address; import com.hayden.model.User; /** * @author HaydenWang * */ public class FieldHandlerMappingTest { private User user; @Before public void init() { Address addr = new Address(); addr.setId(100l); addr.setDetail("Baidu Building"); user = new User(); user.setId(1111L); user.setName("Helen"); user.setAddress(addr); user.setType(User.TYPE_COMMON_USER); } @Test public void mappingTest() { try { // Load Mapping Mapping mapping = new Mapping(); mapping.loadMapping("file:conf//fieldHandlerMapping.xml"); Marshaller marshaller = new Marshaller(); marshaller.setMapping(mapping); FileWriter writer = new FileWriter("out//fieldHandlerTest.xml"); marshaller.setWriter(writer); marshaller.marshal(user); // Create a Reader to the file to unmarshal from FileReader reader = new FileReader("out//fieldHandlerTest.xml"); // Create a new Unmarshaller Unmarshaller unmarshaller = new Unmarshaller(mapping); unmarshaller.setClass(User.class); // Unmarshal the user object User userFromXml = (User) unmarshaller.unmarshal(reader); System.out.println(userFromXml); Assert.assertEquals(user, userFromXml); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } }

以上只是Castor的基本使用方法。

更多请参见:

http://www.castor.org/

此外,sun的xerecs具有类似的功能。

转载于:https://my.oschina.net/u/175660/blog/55924

Castor-解析xml的另外一种方法相关推荐

  1. 解析xml文件的几种方法和原理

    第一种方法 对象模型 API 定义了层次化对象模型来表示 XML 文档.换句话说,对应 XML 语法中的每个概念定义相应的类:元素.属性.实体.文档.解析器读入 XML 文档的时候,建立 XML 语法 ...

  2. java处理解析xml文件的几种方法及每种方法的区别

    文章目录 了解xml xml文件的结构 **特殊处理** **CDATA** 强烈建议 处理xml文件的几种方式 认识Document对象 解析xml文档 该选择哪种方式解析 DOM解析xml文件 D ...

  3. 使用DOM4J解析XML文件的两种方法

     import java.io.File; import java.util.Iterator; import java.util.List; import org.dom4j.Document; ...

  4. java构造和解析json_Java构造和解析Json数据的两种方法详解一

    在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Jso ...

  5. java json解析 代码_Java构造和解析Json数据的两种方法详解一

    在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Jso ...

  6. Java构造和解析Json数据的两种方法详解一

    在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Jso ...

  7. PHP怎么读写XML?(四种方法)

    PHP怎么读写XML?(四种方法) 一.总结 1.这四种方法中,字符串的方式是最原始的方法.SimpleXML和DOM扩展是属于基于树的解析器,把整个文档存储为树的数据结构中,需要把整个文档都加载到内 ...

  8. java构建json_Java构造和解析Json数据的两种方法详解一

    在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Jso ...

  9. Python爬虫入门之爬虫解析提取数据的四种方法

    本文主要介绍了Python爬虫入门之爬虫解析提取数据的四种方法,通过具体的内容向大家展现,希望对大家Python爬虫的学习有所帮助. 基础爬虫的固定模式 笔者这里所谈的基础爬虫,指的是不需要处理像异步 ...

  10. pythonxml解析拿到控件坐标_Python解析xml中dom元素的方法

    本文实例讲述了Python解析xml中dom元素的方法.共享给大家供大家参考.详细实现方法如下: 复制代码 代码如下: from xml.dom import minidom try: xmlfile ...

最新文章

  1. excel打不开怎么修复_SD卡坏了怎么办?一招教你拯救文件!
  2. k8s 自定义dns_K8S 生态周报| Docker v19.03.10 正式发布
  3. 每日一皮:男性同胞,是时候反击了!
  4. Linux shell运行py文件提示command not found
  5. 三个步骤分析网站优化程度
  6. Linux (x86) Exploit 开发系列教程之七 绕过 ASLR -- 第二部分
  7. 转载:使用 GNU Libtool 创建库
  8. Net5 已经来临,让我来送你一个成功
  9. sensei鼠标测试软件,'黑科技'传感器打造出的FPS利器 - 赛睿Sensei 310 鼠标
  10. python的作用域 gbel_[ python ] 全局和局部作用域变量的引用
  11. 说明使用tc编程的一般步骤 c语言,TC编程手册详解-完整版.doc
  12. 5.5 卷积、卷积定理和傅里叶变换的关系及其性质
  13. VS编译器的简单操作
  14. viper4android蓝牙耳机,蝰蛇音效app下载-蝰蛇音效官方版(ViPER4Android FX)下载v2.7.1.0 安卓版-单机手游网...
  15. 腾讯 信鸽测试demo
  16. ec6108v9a精简刷机包_华为悦盒无安装限制固件下载|华为悦盒EC6108V9A第三方精简流畅无安装限制固件 下载 - 巴士下载站...
  17. RuoYi-flowable工作流管理
  18. SDUT 3386 小雷的冰茶几
  19. (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  20. 数据库安全性 --- 控制

热门文章

  1. 从空间分布、空间关系、空间演化、属性数据的扩展与再分析、数据分析扩展的角度举例分析GIS空间分析的特点与重要性,并且写出一句宣传GIS空间分析的广告语
  2. oracle adg 人工干预,ORACLE 12C ADG 之十四 (ADG PDB级闪回(Flashback PDB))
  3. 数据库原理与应用实验指导书 实验一:熟悉SQL Server 2012数据库管理系统
  4. Floyd算法 Java实现
  5. java 滤波算法_双边滤波算法
  6. GB/T2828.1-2003与GB/T2828-1987的差异(转载)
  7. AutoCAD 2008中文版标准教程(第2版)
  8. 图解 K8S(07):调度利器之亲和与反亲和(服务容灾)
  9. go语言基础精修(尚硅谷笔记)
  10. c++中gets用法总结