Вопрос

How can I realize this XML with JAXB? Currently the expires attribute in the grantA,C,B elements is not bounded - but it should. I don't know how to associate an element with an attribute. Do I have to create classes for every grantA,C,B?
XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <customers>
        <customer>
            <name>C1</name>
            <grantA expires="">false</grantA>
            <grantB expires="">true</grantB>
            <grantC expires="">true</grantC>
        </customer>
        <customer>
            <name>C2</name>
            <grantA expires="">false</grantA>
            <grantB expires="">true</grantB>
            <grantC expires="">true</grantC>
        </customer>
        <customer>
            <name>C3</name>
            <grantA expires="">false</grantA>
            <grantB expires="">true</grantB>
            <grantC expires="">false</grantC>
        </customer>
    </customers>

XSD:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="name" type="xs:string" />

    <xs:element name="grantA" type="xs:boolean" />
    <xs:element name="grantB" type="xs:boolean" />
    <xs:element name="grantC" type="xs:boolean" />

    <xs:element name="customers" type="customers" />
    <xs:element name="customer">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="name" />
                <xs:element name="grantA">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:string">
                                <xs:attribute name="expires" type="xs:string" />
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
                <xs:element name="grantB">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:string">
                                <xs:attribute name="expires" type="xs:string" />
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
                <xs:element name="grantC">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:string">
                                <xs:attribute name="expires" type="xs:string" />
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:complexType name="customers">
        <xs:sequence>
            <xs:element ref="customer" minOccurs="0" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>
</xs:schema>

My current state is:

Customers.java:

@XmlRootElement(name = "customers")
public class Customers
{
    private List<Customer>  customerList;

    @XmlElement(name = "customer")
    public List<Customer> getCustomerList()
    {
        if (null == customerList)
        {
            customerList = new ArrayList<Customer>();
        }
        return customerList;
    }

    public void setCustomerList(List<Customer> customers)
    {
        this.customerList = customers;
    }

}

Customer.java

@XmlRootElement(name = "customer")
@XmlType(propOrder = { "name", "grantA", "grantB", "grantC" })
public class Customer
{
    private String  name = "";
    private boolean grantA;
    private boolean grantB;
    private boolean grantC;

    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)   
    @XmlElement(name = "name", required=true)
    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    @XmlElement(name = "grantA", required=true)
    public boolean isGrantA()
    {
        return grantA;
    }

    public void setGrantA(boolean grantA)
    {
        this.grantA = grantA;
    }



    @XmlElement(name = "grantB", required=true)
    public boolean isGrantB()
    {
        return grantB;
    }

    public void setGrantB(boolean grantB)
    {
        this.grantB = grantB;
    }

    @XmlElement(name = "grantC", required=true)
    public boolean isGrantC()
    {
        return grantC;
    }

    public void setGrantC(boolean grantC)
    {
        this.grantC = grantC;
    }


    @Override
    public String toString()
    {
        return "" + name + "[ " + grantA + ", " + grantB + " " + grantC + " ]";
    }

}
Это было полезно?

Решение

You could create a single class, Grant, like this:

@XmlType
public class Grant {
    @XmlAttribute
    private String expires;

    @XmlValue
    private boolean value;

    //getters and setters
}

and in the Customer class map it with different names, like this:

public class Customer
{
    private String  name = "";
    @XmlElement(name="grantA");
    private Grant grantA;

    @XmlElement(name="grantB");
    private Grant grantB;

    @XmlElement(name="grantC");
    private Grant grantC;

    //rest of the code
}

Другие советы

You can use a class to represent a boolean with an expires attribute. The XmlValue annotation is used to denote one of its properties as the content of the element, while another property can be annotated as XmlAttribute.

@XmlType
class BooleanWithExpires {
    @XmlValue public boolean value;
    @XmlAttribute public String expires;
}

Then you can use that type instead of boolean for the different grant members. It is up to you whether you want to use this class to store the data in your Customer objects, or if you store the information in some other way and only convert between that internal storage and BooleanWithExpires in the getters and setters for the XML child elements.

Feel free to change the code from public members to getters and setters if that is more in line with your coding style. Also make sure to use whatever type is most appropriate for expires, e.g. XMLGregorianCalendar. You may also want to denote the expires attribute as required if this is appropriate for you.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top