JAXB генерирует nillable = "true" из Java

Это ошибка?

я нуждаюсь nillable = "true" в моей схеме xsd. Единственный способ создать такой элемент из моего Java-кода - это использовать @XmlElement(nillable = true), право? Но в этом случае я не смогу воспользоваться этим определением, я не смогу проверить, установлен ли элемент в nil, Метод isNil() находится в JAXBElement класс обертки.

Итак, каковы мои варианты здесь - я хочу создать nillable = "true" в моей схеме xsd и быть в состоянии проверить, установлен ли он из моего кода Java.

1 ответ

Решение

Мне нужна nillable = "true" в моей схеме xsd. Единственный способ создать такой элемент из моего Java-кода - это использовать @XmlElement(nillable = true), верно?

Да.

Но в этом случае я не смогу воспользоваться этим определением, я не смогу проверить, установлен ли элемент в ноль. Метод isNil() находится в классе-оболочке JAXBElement.

Ты можешь сделать getFoo() == null чтобы определить, было ли это ноль. Если вы пытаетесь определить, соответствует ли значение null отсутствующему элементу или xsi:nil="true" тогда вам придется сделать больше. Набор не будет сделан для отсутствующих узлов, так что вы можете поместить логику в свой установщик, чтобы отслеживать, был ли установлен нуль из-за элемента с xsi:nil="true,

@XmlElement(nillable=true)
public String getFooString() {
    return fooString;
}

public void setFooString(String foo) {
    this.fooString = foo;
    this.setFoo = true;
}

Если вы не хотите иметь эту дополнительную логику (которая не помогает в любом случае, вам нужно использовать JAXBElement,

@XmlElementRef(name="fooJAXBElement")
public JAXBElement<String> getFooJAXBElement() {
    return fooJAXBElement;
}

public void setFooJAXBElement(JAXBElement<String> fooJAXBElement) {
    this.fooJAXBElement = fooJAXBElement;
}

Модель Java

корень

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlType(propOrder={"fooString", "barString", "fooJAXBElement", "barJAXBElement"})
public class Root {

    private String fooString;
    private String barString;
    private JAXBElement<String> fooJAXBElement;
    private JAXBElement<String> barJAXBElement;

    private boolean setFoo;
    private boolean setBar;

    @XmlElement(nillable=true)
    public String getFooString() {
        return fooString;
    }

    public void setFooString(String foo) {
        this.fooString = foo;
        this.setFoo = true;
    }

    public boolean isSetFooString() {
        return setFoo;
    }

    @XmlElement(nillable=true)
    public String getBarString() {
        return barString;
    }

    public void setBarString(String bar) {
        this.barString = bar;
        this.setBar = true;
    }

    public boolean isSetBarString() {
        return setBar;
    }

    @XmlElementRef(name="fooJAXBElement")
    public JAXBElement<String> getFooJAXBElement() {
        return fooJAXBElement;
    }

    public void setFooJAXBElement(JAXBElement<String> fooJAXBElement) {
        this.fooJAXBElement = fooJAXBElement;
    }

    @XmlElementRef(name="barJAXBElement")
    public JAXBElement<String> getBarJAXBElement() {
        return barJAXBElement;
    }

    public void setBarJAXBElement(JAXBElement<String> barJAXBElement) {
        this.barJAXBElement = barJAXBElement;
    }

}

ObjectFactory

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;

@XmlRegistry
public class ObjectFactory {

    @XmlElementDecl(name="fooJAXBElement")
    public JAXBElement<String> createFooJAXBElement(String string) {
        return new JAXBElement<String>(new QName("fooJAXBElement"), String.class, string);
    }

    @XmlElementDecl(name="barJAXBElement")
    public JAXBElement<String> createBarJAXBElement(String string) {
        return new JAXBElement<String>(new QName("barJAXBElement"), String.class, string);
    }

}

демонстрация

Ниже приведен полный пример, демонстрирующий концепции, рассмотренные выше.

Input.xml

Этот документ содержит 2 элемента, явно помеченных xsi:nil="true" и 2 других сопоставленных элемента, которые отсутствуют.

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

демонстрация

Этот демонстрационный код будет читать в приведенном выше XML и проверять, были ли установлены свойства в результате демаршала.

import java.io.File;
import javax.xml.bind.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum20076018/input.xml");
        Root root = (Root) unmarshaller.unmarshal(xml);

        System.out.println("Was fooString set?  " + root.isSetFooString());
        System.out.println("Was barString set?  " + root.isSetBarString());
        System.out.println("Was fooJAXBElement set?  " + (root.getFooJAXBElement() != null));
        System.out.println("Was barJAXBElement set?  " + (root.getBarJAXBElement() != null));

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

}

Выход

Ниже приведен результат запуска демонстрационного кода. Мы видим, что все установленные проверки правильны, но что выходные данные полностью совпадают с входными данными для JAXBElement свойства.

Was fooString set?  false
Was barString set?  true
Was fooJAXBElement set?  false
Was barJAXBElement set?  true
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
    <fooString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
    <barString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
    <barJAXBElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</root>
Другие вопросы по тегам