2012-01-24 36 views
6

tengo una propiedad de cadena en un objeto anotados como sigue:JAXB - etiquetas vacías sin xsi: nil

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

El resultado después de cálculo de referencias es

<Item xsi:nil="true"/> 

mientras me gustaría que fuera

<Item/> 

ya que el servicio de terceros que acepta mis mensajes XML lo quiere como este último caso. Estoy usando jaxb2. ¿Alguien sabe cómo podría hacer esto?

Muchas gracias

Respuesta

1

Nota: yo soy el EclipseLink JAXB (MOXy) de plomo y un miembro del grupo de expertos JAXB (JSR-222).

El siguiente ejemplo requiere el uso de MOXy como proveedor JAXB. Esto se debe a que JAXB RI no llama al XmlAdapter cuando el campo/propiedad es nulo. Para obtener información sobre la especificación de moxy como su proveedor de JAXB ver:

StringAdapter

El XmlAdapter convertirá el valor de cadena a un objeto con una propiedad anotado con @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

La anotación @XmlJavaTypeAdapter se utiliza para especificar la 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; 
    } 

} 

Demostración

El código siguiente se puede utilizar para demostrar la correlación anteriormente. Se utilizan dos documentos, uno con un elemento Item vacío, y el otro con un elemento Item poblado.

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); 
    } 

} 

salida

El siguiente es el resultado de la ejecución del código de demostración:

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> 

Para más información

0

me encontré cambiando el xsd era más fácil

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

y en su código, cuando se auto generar sus java src/clases

se especificaría nuevo nombre y establezca el nombre en el nombre de objeto que pertenezca a

Cuestiones relacionadas