XML-елемент з атрибутом та вмістом за допомогою JAXB


78

Як я можу створити такий XML за допомогою JAXB?

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

Відповіді:


130

Анотуйте властивості типу та статі за допомогою властивості @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;

}

Для отримання додаткової інформації


10

Правильна схема повинна бути:

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

8

Ось робоче рішення:

Вихід:

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>

Просто хотів додати посилання на подібну відповідь, щоб допомогти тим, хто розглядає це як рішення. Гарна відповідь, до речі. stackoverflow.com/a/15429363/1686575
Джон Манко

ви мене рятуєте! : DI вирішено з використанням @XmlValue
Анджело

4

Оновлене рішення - з використанням схемного рішення, яке ми обговорювали. Це дасть вам відповідь:

Зразок схеми:

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

Створено код

СпортТип:

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 проти схеми в командному рядку


1
Не використовується XSD. Використання анотацій JAXB.
Джеймс,

Звичайно, але ви можете створити дуже простий XSD, щоб описати вищезазначену структуру XML, щоб створити для вас файли коду Java з включеними анотаціями. Крім того, ви можете створити їх вручну, структура анотацій повинна бути в документах. Перевага використання XSD полягає в тому, що дуже швидко змінюється структура та регенеруються файли Java-коду. Це залежить від того, наскільки вам комфортно будь-який із цих підходів. Download.oracle.com/javaee/5/tutorial/doc/bnbah.html
Джим,

1
Дякую за Вашу відповідь. Але моя проблема полягає в тому, як генерувати заданий XML, використовуючи анотації вручну. Як мені потрібно визначити мої файли класу сутності?
Джеймс,

Дивіться моє нове рішення вище, дуже сподіваюся, що це допоможе
Джим,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.