XML-Element mit Attribut und Inhalt unter Verwendung von JAXB

78

Wie kann ich mit JAXB folgendes XML generieren?

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

Antworten:

129

Kommentieren Sie Typ- und Geschlechtseigenschaften mit @XmlAttributeund die Beschreibungseigenschaft mit @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;

}

Für mehr Informationen

bdoughan
quelle
10

Das richtige Schema sollte sein:

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

Der für SportType generierte Code lautet:

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;
    }
}
leugnet
quelle
8

Hier ist eine funktionierende Lösung:

Ausgabe:

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

Ausgabe:

22: 00: 18.471 [main] DEBUG com.grebski.stack.XmlTest - Buch xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<book>
    <price drawable="true">1234</price>
</book>
rgrebski
quelle
Ich wollte nur einen Link zu einer ähnlichen Antwort hinzufügen, um denjenigen zu helfen, die dies als Lösung betrachten. Gute Antwort übrigens. stackoverflow.com/a/15429363/1686575
John Manko
Du rettest mich ! : DI gelöst mit der Nutzung von @XmlValue
Angelo
4

Aktualisierte Lösung - unter Verwendung der von uns diskutierten Schemalösung. Dies bringt Sie zu Ihrer Antwort:

Beispielschema:

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

Sporttyp:

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

}

Ausgabeklassendateien werden erstellt, indem xjc für das Schema in der Befehlszeile ausgeführt wird

Jim
quelle
1
XSD nicht verwenden. Verwenden von JAXB-Anmerkungen.
James
Sicher, aber Sie können eine sehr einfache XSD erstellen, um die obige XML-Struktur zu beschreiben und Java-Codedateien mit aktivierten Anmerkungen für Sie zu generieren. Alternativ können Sie sie manuell erstellen. Die Anmerkungsstruktur sollte sich in den Dokumenten befinden. Der Vorteil der Verwendung einer XSD besteht darin, dass die Struktur sehr schnell geändert und die Java-Codedateien neu generiert werden können. Es hängt davon ab, wie gut Sie mit beiden Ansätzen
Jim
1
Vielen Dank für Ihre Antwort. Mein Problem ist jedoch, wie man gegebenes XML mithilfe von Anmerkungen manuell generiert. Wie muss ich meine Entitätsklassendateien definieren?
James
Sehen Sie meine neue Lösung oben, hoffe wirklich, dass dies hilft
Jim