JAXB - Hello World with Namespace
如果元素带有命名空间,那么处理方式与 JAXB - Hello World 会略有不同。
1. XML Schema:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:ns0="http://www.huey.com/hello/beans/" targetNamespace="http://www.huey.com/hello/beans/" jxb:version="2.0"> <xsd:element name="Greetings" type="ns0:GreetingListType"/> <xsd:complexType name="GreetingListType"> <xsd:sequence> <xsd:element name="Greeting" type="ns0:GreetingType" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="GreetingType"> <xsd:sequence> <xsd:element name="Text" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="language" type="xsd:language"/> </xsd:complexType> </xsd:schema>
2. 编译 schema 生成 Java 类:
xjc hello.xsd // 取默认的包路径,根据命名空间生成
3. 修改生成的 GreetingListType.java 文件,添加 @XmlRootElement,指定根元素的名称和命名空间:
package com.huey.hello.beans; import java.util.ArrayList; import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "GreetingListType", propOrder = { "greeting" }) @XmlRootElement(namespace = "http://www.huey.com/hello/beans/", name = "Greetings") public class GreetingListType { @XmlElement(name = "Greeting", required = true) protected List<GreetingType> greeting; public List<GreetingType> getGreeting() { if (greeting == null) { greeting = new ArrayList<GreetingType>(); } return this.greeting; } }
4. marshal:
public class JaxbUtils { // ... public static <T> String marshal(T obj) { StringWriter writer = new StringWriter(); try { JAXBContext jc = JAXBContext.newInstance(obj.getClass()); Marshaller m = jc.createMarshaller(); m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE ); m.marshal(obj, writer); } catch (JAXBException jbe) { // ... } return writer.toString(); } }
5. 测试 JaxbUtils.marshal 方法:
public class JaxbUtilsTest { @Test public void testMarshal() throws Exception { GreetingListType glt = new GreetingListType(); GreetingType gt1 = new GreetingType(); gt1.setLanguage("en"); gt1.setText("Hello world"); glt.getGreeting().add(gt1); GreetingType gt2 = new GreetingType(); gt2.setLanguage("fr"); gt2.setText("Bonjour, madame"); glt.getGreeting().add(gt2); System.out.println(JaxbUtils.marshal(glt)); } }
6. JaxbUtils.marshal 测试输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <ns2:Greetings xmlns:ns2="http://www.huey.com/hello/beans/"> <Greeting language="en"> <Text>Hello world</Text> </Greeting> <Greeting language="fr"> <Text>Bonjour, madame</Text> </Greeting> </ns2:Greetings>
7. unmarshal:
public class JaxbUtils { // ... public static <T> T unmarshal(Class<T> docClass, InputStream inputStream) throws JAXBException { JAXBContext jc = JAXBContext.newInstance(docClass); Unmarshaller u = jc.createUnmarshaller(); T obj = (T) u.unmarshal(inputStream); return obj; } }
8. 以 JaxbUtils.marshal 的测试输出作为 JaxbUtils.unmarshal 的输入做测试:
public class JaxbUtilsTest { @Test public void testUnmarshal() throws Exception { String path = "/files/hello.xml"; InputStream in = JaxbUtilsTest.class.getResourceAsStream(path); try { GreetingListType greetingList = JaxbUtils.unmarshal(GreetingListType.class, in); List<GreetingType> greetings = greetingList.getGreeting(); for (GreetingType greeting : greetings) { System.out.println(greeting.getLanguage() + ": " + greeting.getText()); } } catch (JAXBException e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(in); } } }
9. JaxbUtils.unmarshal 测试输出:
fr: Bonjour, madame en: Hey, you