JAXB - пустые теги без xsi: nil - PullRequest
       40

JAXB - пустые теги без xsi: nil

6 голосов
/ 24 января 2012

У меня есть свойство String в объекте, аннотированное следующим образом:

@XmlElement(name = "Item", required = true, nillable = true)
private String item;

Результат после маршалинга равен

<Item xsi:nil="true"/>

, в то время как я хотел бы, чтобы оно было

<Item/>

поскольку сторонний сервис, принимающий мои XML-сообщения, хочет этого, как в последнем случае.Я использую jaxb2.Кто-нибудь знает, как я мог это сделать?

Большое спасибо

Ответы [ 2 ]

1 голос
/ 25 января 2012

Примечание: Я EclipseLink JAXB (MOXy) и член JAXB (JSR-222) экспертная группа.

В следующем примере требуется использование MOXy в качестве поставщика JAXB.Это связано с тем, что JAXB RI не вызывает XmlAdapter, когда поле / свойство имеет значение null.Для получения информации об указании MOXy в качестве вашего JAXB-провайдера см .:

StringAdapter

XmlAdapter будетпреобразовать значение String в объект со свойством, помеченным @XmlValue.

package forum8986842;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class StringAdapter extends XmlAdapter<StringAdapter.AdaptedString, String>{

    @Override
    public String unmarshal(AdaptedString adaptedString) throws Exception {
        if(null == adaptedString) {
            return null;
        }
        String string = adaptedString.value;
        if("".equals(string)) {
            return null;
        }
        return string;
    }

    @Override
    public AdaptedString marshal(String string) throws Exception {
        AdaptedString adaptedString = new AdaptedString();
        adaptedString.value = string;
        return adaptedString;
    }

    public static class AdaptedString {
        @XmlValue public String value;
    }

}

Root

Аннотация @XmlJavaTypeAdapter используется для указания XmlAdapter:

package forum8986842;

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name="Root")
public class Root {

    private String item;

    @XmlElement(name = "Item", required = true, nillable = true)
    @XmlJavaTypeAdapter(StringAdapter.class)
    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

}

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

Следующий код можно использовать для демонстрации приведенного выше сопоставления.Используются два документа: один с пустым элементом Item, а другой - с заполненным элементом Item.

package forum8986842;

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

public class Demo {

    private JAXBContext jc;

    public Demo() throws JAXBException {
        jc = JAXBContext.newInstance(Root.class);
    }

    public static void main(String[] args) throws Exception {
        Demo demo = new Demo();
        demo.demo("<Root><Item/></Root>");
        demo.demo("<Root><Item>Hello World</Item></Root>");
    }

    private void demo(String xml) throws JAXBException {
        System.out.println("\n\nINPUT:  " + xml);
        StringReader stringReader = new StringReader(xml);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Root root = (Root) unmarshaller.unmarshal(stringReader);

        System.out.println("ITEM:   " + root.getItem());

        System.out.print("OUTPUT: ");
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
        marshaller.marshal(root, System.out);
    }

}

Вывод

Ниже приводитсявывод из демонстрационного кода:

INPUT:  <Root><Item/></Root>
ITEM:   null
OUTPUT: <Root><Item/></Root>

INPUT:  <Root><Item>Hello World</Item></Root>
ITEM:   Hello World
OUTPUT: <Root><Item>Hello World</Item></Root>

Для получения дополнительной информации

0 голосов
/ 23 апреля 2012

Я нашел, что изменить xsd было проще

<xs:element name="name">
   <xs:complexType/>
</xs:element>

и в вашем коде, когда вы автоматически генерируете java src / classes

вы бы указали новое Имя и задали бы Имя в зависимости от того, какое имя объекта принадлежит

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...