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>