user2254651
user2254651

Reputation:

@XmlElement and useless 'required' parameter

I put @XmlElement(name = "title",required = true) before the javabean property int some_property, and didn't assign a value to some_property. For some reason this property is not occurred in generated XML. So, please, explain the meaning of required

some meaningful parts of the code:

@XmlRootElement(name = "book")
@XmlType(propOrder = { "author", "name", "publisher", "isbn" })
public class Book {

private String name;
private String author;
private String publisher;
private String isbn;

// If you like the variable name, e.g. "name", you can easily change this
// name for your XML-Output:
@XmlElement(name = "title",required = true)
public String getName() {
    return name;
}
....

Somewhere int the Main :

    // create books
    Book book1 = new Book();
    book1.setIsbn("978-0060554736");

    book1.setAuthor("Neil Strauss");
    book1.setPublisher("Harpercollins");
    bookList.add(book1);


    Book book2 = new Book();
    book2.setIsbn("978-3832180577");
    book2.setName("Feuchtgebiete");
    book2.setAuthor("Charlotte Roche");
    book2.setPublisher("Dumont Buchverlag");
    bookList.add(book2);

    JAXBContext context = JAXBContext.newInstance(Bookstore.class);
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

    // Write to System.out
    m.marshal(bookstore, System.out);

    // Write to File
    m.marshal(bookstore, new File(BOOKSTORE_XML));

    // get variables from our xml file, created before
    System.out.println();
    System.out.println("Output from our XML File: ");
    Unmarshaller um = context.createUnmarshaller();
    Bookstore bookstore2 = (Bookstore) um.unmarshal(new FileReader(BOOKSTORE_XML));
    ArrayList<Book> list = bookstore2.getBooksList();

Upvotes: 17

Views: 49049

Answers (3)

bdoughan
bdoughan

Reputation: 148977

What required Does on @XmlElement

The required property on the @XmlElement annotation affects the XML schema that is generated from Java classes.

Domain Model (Root)

Below is a simple Java model. Note how the bar property has required=true and the foo property does not.

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElement
    private String foo;

    @XmlElement(required=true)
    private String bar;

    @XmlElement(nillable=true)
    private String baz;

}

Demo Code

Below is some code that demonstrates how to generate an XML schema using the JAXBContext.

import java.io.IOException;
import javax.xml.bind.*;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;

public class GenerateSchema {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        jc.generateSchema(new SchemaOutputResolver() {
            @Override
            public Result createOutput(String namespaceUri,
                    String suggestedFileName) throws IOException {
                StreamResult result = new StreamResult(System.out);
                result.setSystemId(suggestedFileName);
                return result;
            }
        });
    }

}

Generated XML Schema

Below is the resulting XML schema note how the XML element corresponding to the foo field has minOccurs="0" while the XML element corresponding to the bar field (which was annotated with @XmlElement(required=true) does not. This is because the default minOccurs is 1 meaning it's required.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="root" type="root"/>
  <xs:complexType name="root">
    <xs:sequence>
      <xs:element name="foo" type="xs:string" minOccurs="0"/>
      <xs:element name="bar" type="xs:string"/>
      <xs:element name="baz" type="xs:string" nillable="true" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

If You Want an Element for null Values

Domain Model (Root)

The baz field has been annotated with @XmlElement(nillable=true). If the value is null the resulting XML element will leverage the xsi:nil attribute. Without this annotation null values will be treated as absent nodes.

import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

    @XmlElement
    private String foo;

    @XmlElement(required=true)
    private String bar;

    @XmlElement(nillable=true)
    private String baz;

}

Demo Code

import javax.xml.bind.*;

public class MarshalDemo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        Root root = new Root();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(root, System.out);
    }

}

Output

Below is the resulting XML from running the demo code.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <baz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</root>

Upvotes: 26

Norw&#230;
Norw&#230;

Reputation: 1575

From: http://docs.oracle.com/javaee/5/api/javax/xml/bind/annotation/XmlElement.html

public abstract boolean required

Customize the element declaration to be required. If required() is true, then Javabean property is mapped to an XML schema element declaration with minOccurs="1". maxOccurs is "1" for a single valued property and "unbounded" for a multivalued property.

If required() is false, then the Javabean property is mapped to XML Schema element declaration with minOccurs="0". maxOccurs is "1" for a single valued property and "unbounded" for a multivalued property.

Your property is mapped to an element that is (hopefully) declared as required in the schema. Your generated XML is not compliant to that particular schema, which is more or less what I expected from an instance that does not "play by the rules" it has laid out

Upvotes: 1

michal
michal

Reputation: 1806

Could you show us a sample of your code and generated xml? According to docs:

If required is true, then Javabean property is mapped to an XML schema element declaration with minOccurs="1". maxOccurs is "1" for a single valued property and "unbounded" for a multivalued property.

Upvotes: 0

Related Questions