2009-12-15 12 views
5

Próbuję out Simple XML serializer. Bardziej interesuje mnie deserializacja z XML-> Java. Oto mój kod jako test jednostki:Prosta deserializacja XML

import java.io.StringReader; 
import java.io.StringWriter; 

import junit.framework.TestCase; 

import org.simpleframework.xml.Attribute; 
import org.simpleframework.xml.Root; 
import org.simpleframework.xml.Serializer; 
import org.simpleframework.xml.core.Persister; 

public class SimpleTest extends TestCase { 
    public void testWriting() throws Exception { 
     StringWriter writer = new StringWriter(); 
     Address address = new Address("1234 Main Street", "San Francisco", "CA"); 
     Serializer serializer = new Persister(); 

     serializer.write(address, writer); 
     System.out.println("Wrote: " + writer.getBuffer()); 
    } 

    public void testReading() throws Exception { 
     String input = "<address street='1234 Main Street' city='San Francisco' state='CA'/>"; 
     Serializer serializer = new Persister(); 
     System.out.println("Read back: " + serializer.read(Address.class, new StringReader(input))); 
    } 
} 

@Root 
class Address { 
    @Attribute(name="street") 
    private final String street; 

    @Attribute(name="city") 
    private final String city; 

    @Attribute(name="state") 
    private final String state; 

    public Address(@Attribute(name="street") String street, @Attribute(name="city") String city, @Attribute(name="state") String state) { 
     super(); 
     this.street = street; 
     this.city = city; 
     this.state = state; 
    } 

    @Override 
    public String toString() { 
     return "Address [city=" + city + ", state=" + state + ", street=" + street + "]"; 
    } 
} 

To działa, ale powtarzające @Attribute adnotacje (w zakresie i na argumencie konstruktora) w klasie Adres wyglądać brzydko. Czy jest jakiś sposób, aby:

  • mają proste dowiedzieć się nazwę atrybutu od nazwy pola?
  • mają proste serializacji ignorować, tak że mogę uciec z adnotacji albo pola lub argument konstruktora?
+3

Jeśli szukasz łatwej do sformatowania XML-> Java i nie jesteś przywiązany do konkretnego pakietu, oto alternatywa: http://sourceforge.net/projects/practicalxml/ (pamiętaj, że nie umieściłem tego jako odpowiedź, ponieważ wydajesz się bardzo szczęśliwy, co nie jest dobrym sposobem na traktowanie ludzi, którzy próbują ci pomóc) – kdgregory

+0

@kdgregory Dzięki, nie jestem przywiązany do konkretnej paczki - sprawdzę praktycznyxml. Proszę nie brać zbyt pochopnie opinii osobistych - proponowane sugestie nie były nigdzie bliskie rozwiązania mojego problemu i były głośne, IMO. –

+1

@kdgregory Po chwili namysłu byłem zbyt szczęśliwy. Przepraszam wszystkich. –

Odpowiedz

1

Nie potrzebuję wszystkich tych powtórzeń i atrybutów dodatkowych adnotacji. Jeśli nazwa jest taka sama jak atrybut obiektu, będzie używana domyślnie.

więc można po prostu zadeklarować ją jako:

@Root 
class Address { 
    @Attribute 
    private final String street; 

    @Attribute 
    private final String city; 

    @Attribute 
    private final String state; 

    public Address(String street, String city, String state) { 
     super(); 
     this.street = street; 
     this.city = city; 
     this.state = state; 
    } 

    @Override 
    public String toString() { 
     return "Address [city=" + city + ", state=" + state + ", street=" + street + "]"; 
    } 
} 
+0

Nie, to nie działa, przynajmniej w wersji 2.1.3. –

+0

Mój zły, nie zwracałem baczniej uwagi, że chciałbyś mieć niezmienny adres. Na podstawie bieżącego proste, powinieneś mieć duplikat tagu @Attribute, ponieważ użył adnotacji na atrybut do serializacji, a konstruktor do deserializacji. Możesz uciec bez tagu nazwy w atrybucie, ale nie w parametrach konstruktora, ponieważ kompilator śledzi go tylko według kolejności, a nie według nazwy. –

+0

Zależy od tego, jaki cel chcesz osiągnąć. Oczywiście możesz zmienić klasę i wymuszać niezmienność ręcznie w ustawiaczu. Ale znowu kod stanie się brzydki. Pomiędzy tymi dwoma, mógłbym po prostu wybrać opcję podwójnych adnotacji. –

0

Java serializacji wszystkich członków klasy domyślnie jeśli realizują one Serializable i przestrzegać składni JavaBeans.

+0

Myślę, że źle zrozumiałeś pytanie. Chcę deserializera XML-> Java. –

+0

Serializacja Java działa w obie strony. Jeśli serializuje się obiekty Java do formatu XML przy użyciu serializacji Java, można również przekształcić je z XML na obiekty Java. Proces jest przejrzysty i elastyczny.W jednej aplikacji korzystam z serializacji/deserializacji XML w Javie, aby zapisywać drzewa obiektów na dysk i czytać je na żądanie użytkownika - mówimy o setkach tysięcy plików - i to działa, moim zdaniem. Sprawdź przykłady na http://java.sys-con.com/node/37550 - klasami kluczowymi są 'XMLEncoder' i' XMLDecoder'. – spork

0

Miałem podobne obawy, ale z dość skomplikowanymi strukturami obiektów. Rozwiązałem to, używając biblioteki JAXB do porządkowania i usuwania ładunków, co jest dość powszechne. Możesz również rozważyć całkowite oddzielenie logiki od klasy języka Java za pomocą aspektów - możesz potraktować wszystkie adnotacje w oddzielnym aspekcie, co spowoduje, że klasa Java będzie w pełni czysta dzięki marnowaniu adnotacji.