如何使用 JAXB 生成以下 XML?
<sport type="" gender=""> sport description </sport>
Updated Solution - using the schema solution that we were debating. This gets you to your answer:
Sample Schema:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Sport" xmlns:tns="http://www.example.org/Sport" elementFormDefault="qualified" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"> <complexType name="sportType"> <attribute name="type" type="string" /> <attribute name="gender" type="string" /> </complexType> <element name="sports"> <complexType> <sequence> <element name="sport" minOccurs="0" maxOccurs="unbounded" type="tns:sportType" /> </sequence> </complexType> </element>
Code Generated
SportType:
package org.example.sport; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sportType") public class SportType { @XmlAttribute protected String type; @XmlAttribute protected String gender; public String getType() { return type; } public void setType(String value) { this.type = value; } public String getGender() { return gender; } public void setGender(String value) { this.gender = value; } }
Sports:
package org.example.sport; 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.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = { "sport" }) @XmlRootElement(name = "sports") public class Sports { protected List<SportType> sport; public List<SportType> getSport() { if (sport == null) { sport = new ArrayList<SportType>(); } return this.sport; } }
Output class files are produced by running xjc against the schema on the command line
Annotate type and gender properties with @XmlAttribute and the description property with @XmlValue:
@XmlAttribute
@XmlValue
package org.example.sport; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement public class Sport { @XmlAttribute protected String type; @XmlAttribute protected String gender; @XmlValue; protected String description; }
For More Information
The correct scheme should be:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/Sport" xmlns:tns="http://www.example.org/Sport" elementFormDefault="qualified" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"> <complexType name="sportType"> <simpleContent> <extension base="string"> <attribute name="type" type="string" /> <attribute name="gender" type="string" /> </extension> </simpleContent> </complexType> <element name="sports"> <complexType> <sequence> <element name="sport" minOccurs="0" maxOccurs="unbounded" type="tns:sportType" /> </sequence> </complexType> </element>
Code generated for SportType will be:
package org.example.sport; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "sportType") public class SportType { @XmlValue protected String value; @XmlAttribute protected String type; @XmlAttribute protected String gender; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getType() { return type; } public void setType(String value) { this.type = value; } public String getGender() { return gender; } public void setGender(String value) { this.gender = value; } }
Here is working solution:
Output:
public class XmlTest { private static final Logger log = LoggerFactory.getLogger(XmlTest.class); @Test public void createDefaultBook() throws JAXBException { JAXBContext jaxbContext = JAXBContext.newInstance(Book.class); Marshaller marshaller = jaxbContext.createMarshaller(); StringWriter writer = new StringWriter(); marshaller.marshal(new Book(), writer); log.debug("Book xml:\n {}", writer.toString()); } @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "book") public static class Book { @XmlElementRef(name = "price") private Price price = new Price(); } @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "price") public static class Price { @XmlAttribute(name = "drawable") private Boolean drawable = true; //you may want to set default value here @XmlValue private int priceValue = 1234; public Boolean getDrawable() { return drawable; } public void setDrawable(Boolean drawable) { this.drawable = drawable; } public int getPriceValue() { return priceValue; } public void setPriceValue(int priceValue) { this.priceValue = priceValue; } } }
22:00:18.471 [main] DEBUG com.grebski.stack.XmlTest - Book xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <book> <price drawable="true">1234</price> </book>