2012-06-03 13 views
7

Wie kann ich null Wert abrufen, wenn unmarshalling, wenn innerhalb XML-Attributwert leer ist? Jetzt mache ich in meinem Getter Überprüfung für null:JAXB gibt null anstatt leere Zeichenfolge zurück

public String getLabel() { 
    if (label.isEmpty()) { 
     return null; 
    } 
    else { 
     return label; 
    } 
} 

Aber kann einen anderen existiere, eleganteren Weg?

Danke.

+1

Warum sollte null eine bessere Option sein? Anstatt zu überprüfen, ob die Zeichenfolge null ist - was Sie nach dem Aufruf tun müssen, um NPE zu vermeiden - prüfen Sie, ob sie leer ist und Sie fertig sind. –

Antwort

10

Ich denke, Ihre XML mehr oder weniger wie folgt aussieht:

<myElement></myElement> 

Dies ist leider bedeutet, dass Sie einen leeren String übergeben.

Wenn Sie null übergeben möchten, haben Sie zwei Möglichkeiten:

  1. Sie dieses Tag nicht passieren überhaupt (Ihr XML sollte <myElement/> Tag überhaupt nicht enthalten).
  2. Verwenden Sie xsi:nil.

Wenn xsi:nil verwenden, müssen Sie zunächst Ihr XML-Element deklarieren (in XSD-Datei) als nilable, wie folgt aus:

<xsd:element name="myElement" nillable="true"/> 

Dann die null Wert in XML passieren dies tun:

<myElement xsi:nil="true"/> 

oder dies:

<myElement xsi:nil="true"></myElement> 

Auf diese Weise weiß JAXB, dass Sie statt einer leeren Zeichenfolge null übergeben.

6

Die answer given by npe ist eine gute, und die Angabe, wie Sie wollen null vertreten wäre meine Empfehlung auch. Haben xsi:nil vermarshallten möchten Sie Ihre Immobilie mit Anmerkungen versehen (siehe Binding to JSON & XML - Handling Null):

@XmlElement(nillable=true) 
public String getLabel() { 
    return label; 
} 

Wenn Sie nicht wollen, Ihre XML-Darstellung ändern, dann können Sie verwenden, um eine XmlAdapter:

EmptyStringAdapter

package forum10869748; 

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

public class EmptyStringAdapter extends XmlAdapter<String, String> { 

    @Override 
    public String unmarshal(String v) throws Exception { 
     if("".equals(v)) { 
      return null; 
     } 
     return v; 
    } 

    @Override 
    public String marshal(String v) throws Exception { 
     return v; 
    } 

} 

Foo

Sie verweisen auf eine XmlAdapter mithilfe der @XmlJavaTypeAdapter Annotation. Wenn Sie möchten, dass XmlAdapter auf alle Strings angewendet wird, können Sie es auf der Paketebene registrieren (siehe JAXB and Package Level XmlAdapters).

package forum10869748; 

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

@XmlRootElement 
public class Foo { 

    private String label; 

    @XmlJavaTypeAdapter(EmptyStringAdapter.class) 
    public String getLabel() { 
     return label; 
    } 

    public void setLabel(String label) { 
     this.label = label; 
    } 

} 

Demo

package forum10869748; 

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

public class Demo { 

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

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum10869748/input.xml"); 
     Foo foo = (Foo) unmarshaller.unmarshal(xml); 

     System.out.println(foo.getLabel()); 
    } 

} 

input.xml

<?xml version="1.0" encoding="UTF-8"?> 
<foo> 
    <label></label> 
</foo> 

Output

null 
+1

Sehr nützliches Stück Code - als ein Beispiel dafür, was man mit 'JAXB' machen kann. Aber meiner Meinung nach ist das, was Sie hier vorschlagen, gefährlich. Das Behandeln leerer Strings als Nullen ohne jegliche Benachrichtigung, dass Nullen im Vertrag möglich sind ("WSDL", "XSD"), ist eine Art Affenflicken, und es ist fast sicher, dass jemand eines Tages wirklich, wirklich frustriert wird, dies zu debuggen. Wenn Sie leere Strings behandeln und die Nullen gleich machen wollen, würde ich vorschlagen, [isBlank (String) aus commons-lang] (http://commons.apache.org/lang/api-2.5/org/apache/commons/ lang/StringUtils.html # isBlank% 28java.lang.String% 29) – npe

+2

@npe - Ich stimme zu, dass die Angabe von '@XmlElement (nillable = true)' und die explizite Darstellung von null in XML der beste Weg ist (ich habe sogar Upvoted gemacht Deine Antwort). Ich habe diese Antwort für diese Leute hinzugefügt, wie kann ich die XML-Darstellung nicht ändern. Ich halte es nicht für gefährlich, solange der Benutzer konsistent ist mit dem, was leere Elemente bedeuten. –

Verwandte Themen