不使用注释的 Java 代码到 XML/XSD
我需要将 Java 类编组和解组为 XML.不属于我的类,我无法添加注释以便我可以使用 JAXB.
I need to marshall and unmarshall a Java class to XML. The class in not owned by me, that I cannot add anotations so that I can use JAXB.
有没有给定约束条件下将 Java 转换为 XML 的好方法?
Is there a good way to convert the Java to XML with the given contraint?
另外,我认为一个工具可能会有所帮助,但如果有一些 Java API 可以做同样的事情,我会更感兴趣.
Also, thought a tool may be helpful, but I would be more intersted it there is some Java API to do the same.
推荐答案
注意:我是EclipseLink JAXB (MOXy) 领导和 JAXB (JSR-222) 专家组.
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
域模型
我将使用以下域模型来回答这个问题.请注意模型上没有 JAXB 注释.
I will use the following domain model for this answer. Note how there are no JAXB annotations on the model.
客户
package forum11693552;
import java.util.*;
public class Customer {
private String firstName;
private String lastName;
private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<PhoneNumber> getPhoneNumbers() {
return phoneNumbers;
}
public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
this.phoneNumbers = phoneNumbers;
}
}
电话号码
package forum11693552;
public class PhoneNumber {
private String type;
private String number;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
选项 #1 - 任何 JAXB (JSR-222) 实现
JAXB 是异常配置,这意味着您只需要在您希望映射行为与默认行为不同的地方添加注释.下面是一个示例的链接,该示例演示了如何在没有注释的情况下使用任何 JAXB impl:
JAXB is configurartion by exception, this means you only need to add annotations where you want the mapping behaviour to differ from the default. Below is a link to an example demonstrating how to use any JAXB impl without annotations:
演示
package forum11693552;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Customer customer = new Customer();
customer.setFirstName("Jane");
customer.setLastName("Doe");
PhoneNumber workPhone = new PhoneNumber();
workPhone.setType("work");
workPhone.setNumber("555-1111");
customer.getPhoneNumbers().add(workPhone);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBElement<Customer> rootElement = new JAXBElement<Customer>(new QName("customer"), Customer.class, customer);
marshaller.marshal(rootElement, System.out);
}
}
输出
<customer>
<firstName>Jane</firstName>
<lastName>Doe</lastName>
<phoneNumbers>
<number>555-1111</number>
<type>work</type>
</phoneNumbers>
</customer>
更多信息
- http://wiki.eclipse.org/EclipseLink/Examples/MOXy/入门/基础知识
选项 #2 - EclipseLink JAXB (MOXy) 的外部映射文档
如果您确实想自定义映射,那么您可能会对 MOXy 的外部映射文档扩展感兴趣.示例映射文档如下所示:
If you do want to customize the mappings, then you may be interested in MOXy's external mapping document extension. A sample mapping document looks like the following:
oxm.xml
<?xml version="1.0"?>
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum11693552">
<java-types>
<java-type name="Customer">
<xml-root-element />
<java-attributes>
<xml-element java-attribute="firstName" name="first-name" />
<xml-element java-attribute="lastName" name="last-name" />
<xml-element java-attribute="phoneNumbers" name="phone-number" />
</java-attributes>
</java-type>
<java-type name="PhoneNumber">
<java-attributes>
<xml-attribute java-attribute="type" />
<xml-value java-attribute="number" />
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
jaxb.properties
要启用 MOXy 作为您的 JAXB 提供程序,您需要在与您的域模型相同的包中包含一个名为 jaxb.properties
的文件,其中包含以下条目(请参阅:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):
To enable MOXy as your JAXB provider you need to include a file called jaxb.properties
in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
演示
当使用 EclipseLink MOXy 作为您的 JAXB 提供程序时(请参阅),您可以在引导 JAXBContext
When using EclipseLink MOXy as your JAXB provider (see), you can leverage the external mapping document when you bootstrap your JAXBContext
package forum11693552;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.namespace.QName;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String,Object>(1);
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum11693552/oxm.xml");
JAXBContext jc = JAXBContext.newInstance(new Class[] {Customer.class}, properties);
Customer customer = new Customer();
customer.setFirstName("Jane");
customer.setLastName("Doe");
PhoneNumber workPhone = new PhoneNumber();
workPhone.setType("work");
workPhone.setNumber("555-1111");
customer.getPhoneNumbers().add(workPhone);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBElement<Customer> rootElement = new JAXBElement<Customer>(new QName("customer"), Customer.class, customer);
marshaller.marshal(rootElement, System.out);
}
}
输出
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<first-name>Jane</first-name>
<last-name>Doe</last-name>
<phone-number type="work">555-1111</phone-number>
</customer>
更多信息
- http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html
- http://blog.bdoughan.com/2012/04/extending-jaxb-representing-metadata-as.html
相关文章