Java使用JAXB(Java Architecture for XML Binding)將xml檔內容解析(unmarshal)為Java物件範例如下。
例如employee.xml
位在Maven專案的src/main/resources
,內容如下。
employee.xml
<?xml version="1.0" encoding="UTF-8" ?>
<employee>
<id>100</id>
<name>John</name>
<email>john@abc.com</email>
<age>29</age>
<onBoardDate>2021-04-19</onBoardDate>
<department>
<id>22</id>
<name>Marketing</name>
<manager>
<id>52</id>
<name>Mary</name>
<email>mary@abc.com</email>
</manager>
</department>
<exts>
<ext>201</ext>
<ext>202</ext>
</exts>
</employee>
在要轉成的Java物件Employee
類別上使用JAXB的annotation來標示對應的xml元素如下。
@XmlRootElement
標註在類別,代表xml的根元素,也就是上面的<employee>
。@XmlElement
標註在類別欄位,代表xml元素,也就是上面的<id>
、<name>
、<email>
、<age>
、<onBoardDate>
、<department>
等。@XmlType
標註在類別,用來指定輸出順序。@XmlAccessorType
標註在類別,用來決定欄位是否綁定對應的xml元素,若無設定此注釋則預設為XmlAccessType.PUBLIC_MEMBER
。XmlAccessType.FIELD
:除了靜態和tranient以外的欄位都會綁定到xml。XmlAccessType.NONE
:所有欄位皆不綁定到xmlXmlAccessType.PROPERTY
:有getter和setter的欄位才會綁定到xml:XmlAccessType.PUBLIC_MEMBER
:public欄位或有public getter setter的欄位才會綁定到xml。
@XmlElementWrapper
標註集合欄位。代表集合xml元素的外包元素,也就是上面的<exts>
Employee
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Arrays;
import java.util.Date;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"id", "name", "email", "age", "onBoardDate", "department", "exts"})
@XmlRootElement(name = "employee")
public class Employee {
private int id;
private String name;
private String email;
private int age;
@XmlJavaTypeAdapter(DateAdapter.class)
private Date onBoardDate;
private Department department;
@XmlElementWrapper(name = "exts")
@XmlElement(name = "ext")
private String[] exts;
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
", onBoardDate=" + onBoardDate +
", department=" + department +
", exts=" + Arrays.toString(exts) +
'}';
}
// getters and setters
}
xml內層元素的對應類別。可獨立為一個類別或以公開靜態巢狀類別(public static nested class)的型式存在Employee
。
Department
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"id", "name", "manager"})
public class Department {
private int id;
private String name;
private Manager manager;
@Override
public String toString() {
return "Department{" +
"id=" + id +
", name='" + name + '\'' +
", manager=" + manager +
'}';
}
// getters and setters
}
Manager
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"id", "name", "email"})
public class Manager {
private int id;
private String name;
private String email;
@Override
public String toString() {
return "Manager{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
// getters and setters
}
讀取的值皆為字串,如果要轉成特定型態如日期Date
,則可自訂一個實作XmlAdapter
的類別做為@XmlJavaTypeAdapter
的參數並掛在要轉換的欄位上進行轉換。例如下面的DateAdapter
。
DateAdapter
import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateAdapter extends XmlAdapter<String, Date> {
private static final String PATTERN = "yyyy-MM-dd";
@Override
public Date unmarshal(String v) throws Exception {
return new SimpleDateFormat(PATTERN).parse(v);
}
@Override
public String marshal(Date v) {
return new SimpleDateFormat(PATTERN).format(v);
}
}
轉換方式如下。
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
public class Main {
private static final String XML_PATH = "src/main/resources/employee.xml";
public static void main(String[] arges) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(Employee.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Employee employee = (Employee) unmarshaller.unmarshal(new File(XML_PATH));
System.out.println(employee);
}
}
印出結果
Employee{id=100, name='John', email='john@abc.com', age=29, onBoardDate=Mon Apr 19 00:00:00 CST 2021, department=Department{id=22, name='Marketing', manager=Manager{id=52, name='Mary', email='mary@abc.com'}}, exts=[201, 202]}
轉換的物件內容如下
Employee{
id=100,
name='John',
email='john@abc.com',
age=29,
onBoardDate=Mon Apr 19 00:00:00 CST 2021,
department=Department{
id=22,
name='Marketing',
manager=Manager{
id=52,
name='Mary',
email='mary@abc.com'
}},
exts=[201, 202]
}
沒有留言:
張貼留言