備註:我是EclipseLink JAXB (MOXy)的領導和JAXB (JSR-222)專家組的成員。
JAXB中的Binder
機制可能是您正在尋找的。它不允許將DOM節點轉換爲域對象,但它確實保持域對象與其對應的DOM節點之間的鏈接。
注:使用莫西作爲JAXB提供商時下面的代碼都成功了,但使用包含在JDK版本我正好運行JAXB的IMPL時拋出異常。
Java模型
我將使用以下域模型的這個例子。你需要
客戶
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class Customer {
private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
@XmlElementWrapper
@XmlElement(name="phoneNumber")
public List<PhoneNumber> getPhoneNumbers() {
return phoneNumbers;
}
}
******中國
import javax.xml.bind.annotation.*;
public class PhoneNumber {
private String type;
private String number;
@XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@XmlValue
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
jaxb.properties
要指定莫西爲您的JAXB提供者包括在名爲jaxb.properties
文件相同的封裝與下面進入你的領域模型(見:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
XML(輸入。XML)
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<phoneNumbers>
<phoneNumber type="work">555-1111</phoneNumber>
<phoneNumber type="home">555-2222</phoneNumber>
</phoneNumbers>
</customer>
演示代碼
在演示代碼下面我將做到以下幾點:
- 使用XPath找到一個子元素,然後使用
Binder
找到相應的域對象。
- 更新域對象並使用
Binder
將更改應用到DOM。
- 更新DOM並使用
Binder
將更改應用於域對象。
演示
import javax.xml.bind.Binder;
import javax.xml.bind.JAXBContext;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
public class Demo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse("src/forum16599580/input.xml");
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Binder<Node> binder = jc.createBinder();
binder.unmarshal(document);
// Use Node to Get Object
Node phoneNumberElement = (Node) xpath.evaluate("/customer/phoneNumbers/phoneNumber[2]", document, XPathConstants.NODE);
PhoneNumber phoneNumber = (PhoneNumber) binder.getJAXBNode(phoneNumberElement);
// Modify Object to Update DOM
phoneNumber.setNumber("555-2OBJ");
binder.updateXML(phoneNumber);
System.out.println(xpath.evaluate("/customer/phoneNumbers/phoneNumber[2]", document, XPathConstants.STRING));
// Modify DOM to Update Object
phoneNumberElement.setTextContent("555-2DOM");
binder.updateJAXB(phoneNumberElement);
System.out.println(phoneNumber.getNumber());
}
}
輸出
555-2OBJ
555-2DOM
您是否掌握了XML的外觀? –
是的,我完全控制了XML及其模式。 – TechnocratiK