XML element with attribute and content using JAXB
How can I generate the following XML using JAXB?
<sport type="" gender=""> sport description </sport> Define type and gender properties using @XmlAttribute and description properties using @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; } Additional 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> The 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; } } Updated solution - using the circuit solution that we discussed. This will give you the answer:
Example circuit:
<?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> Generated code
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; } } Sport:
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 created by running xjc according to the scheme on the command line
Here is a 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; } } } Output:
22: 00: 18.471 [main] DEBUG com.grebski.stack.XmlTest - xml book:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <book> <price drawable="true">1234</price> </book>