XML-элемент с атрибутом и контентом с использованием JAXB

Как я могу сгенерировать следующий XML с помощью JAXB?

<sport type="" gender="">
    sport description
</sport>

Ответ 1

Определить тип и гендерные свойства с помощью @XmlAttribute и свойства description с помощью @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;

}

Дополнительная информация

Ответ 2

Правильная схема должна быть:

<?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>

Сгенерированный для 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 {
    @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;
    }
}

Ответ 3

Обновленное решение - с помощью решения схемы, которое мы обсуждали. Это даст вам ответ:

Пример схемы:

<?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>

Созданный код

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;
    }

}

Спорт:

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;
    }

}

Файлы выходных классов создаются путем запуска xjc по схеме в командной строке

Ответ 4

Вот рабочее решение:

Вывод:

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 [главная] DEBUG com.grebski.stack.XmlTest - Книга xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
    <price drawable="true">1234</price>
</book>