Zasady JAXB w przypadku ArrayList

0

Mam problem z "załapaniem" zasad JAXB w przypadku ArrayList. Poniżej wstawiam uproszczony przykład, w jaki sposób zapisuję do XMLa jedną listę.

import java.io.File;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class Test
{ 
    Listy listy;
    ArrayList<String> listaImion;

    public static void main(String[] args)
    {
        Test proba = new Test();
        proba.zapiszListeDoXML();   
    }   

    public void zapiszListeDoXML()
    {
        listaImion = new ArrayList<String>();
        listaImion.add("Ala");
        listaImion.add("Ola");
        listaImion.add("Ula");

        listy = new Listy();
        listy.setList(listaImion);

          JFileChooser fileCh = new JFileChooser();

           if (fileCh.showSaveDialog(null)==JFileChooser.APPROVE_OPTION)
           {
               File nazwaPliku = fileCh.getSelectedFile();    

             try 
             {
                JAXBContext jaxbContext = JAXBContext.newInstance(Listy.class);
                Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
                jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                jaxbMarshaller.marshal(listy, nazwaPliku);
                jaxbMarshaller.marshal(listy, System.out);
             }
             catch (JAXBException f) 
             {
                f.printStackTrace();
             }  
          }
    }
}

i

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Listy")
public class Listy
{
    List<String> list = new ArrayList<String>();

    public List<String> getList() 
    {
        return list;
    }

    @XmlElement(name = "Value")
    public void setList(List<String> list) 
    {
        this.list = list;
    }
}

Nie wiem w jaki sposób mógłbym zapisać więcej list, np. jeszcze listaCyfr. Czy konieczne jest stworzenie dodatkowej klasy?

0

Pomoże ktoś?
Gdy zapisuję dwie listy w poniższy sposób:

import java.io.File;
import java.util.ArrayList;
import javax.swing.JFileChooser;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

public class Test
{ 
    Listy listy;
    ArrayList<String> listaImion;
    ArrayList<Integer> listaCyfr;

    public static void main(String[] args)
    {
        Test test = new Test();
        test.zapiszListeDoXML();    
    }   

    public void zapiszListeDoXML()
    {
        listaImion = new ArrayList<String>();
        listaImion.add("Ala");
        listaImion.add("Ola");
        listaImion.add("Ula");

        listaCyfr = new ArrayList<Integer>();
        listaCyfr.add(18);
        listaCyfr.add(20);
        listaCyfr.add(22);

        listy = new Listy();
        listy.setListaImion(listaImion);
        listy.setListaCyfr(listaCyfr);

          JFileChooser fileCh = new JFileChooser();

           if (fileCh.showSaveDialog(null)==JFileChooser.APPROVE_OPTION)
           {
               File nazwaPliku = fileCh.getSelectedFile();    

             try 
             {
                JAXBContext jaxbContext = JAXBContext.newInstance(Listy.class);
                Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
                jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                jaxbMarshaller.marshal(listy, nazwaPliku);
                jaxbMarshaller.marshal(listy, System.out);
             }
             catch (JAXBException f) 
             {
                f.printStackTrace();
             }  
          }
    }
}
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Listy")
public class Listy
{
    List<String> listaImion = new ArrayList<String>();

    public List<String> getListaImion() 
    {
        return listaImion;
    }

    @XmlElement(name = "Value")
    public void setListaImion(List<String> listaImion) 
    {
        this.listaImion = listaImion;
    }   

     List<Integer> listaCyfr = new ArrayList<Integer>();

        public List<Integer> getListaCyfr() 
        {
            return listaCyfr;
        }

        @XmlElement(name = "Value")
        public void setListaCyfr(List<Integer> listaCyfr) 
        {
            this.listaCyfr = listaCyfr;
        }
}

otrzymuję taki wynik:

<Listy>
    <Value>18</Value>
    <Value>20</Value>
    <Value>22</Value>
    <Value>Ala</Value>
    <Value>Ola</Value>
    <Value>Ula</Value>
</Listy>

A zależałoby mi na takim:

<Listy>
   <ListaCyfr>
       <Value>18</Value>
       <Value>20</Value>
       <Value>22</Value>
   </ListaCyfr>
   <ListaImion>
       <Value>Ala</Value>
       <Value>Ola</Value>
       <Value>Ula</Value>
   </ListaImion>
</Listy>

Czy istnieje możliwość dodania w klasie Listy jakiejś adnotacji, która pozwoli otrzymać taki zapis?

1

sprawdź :

@XmlElementWrapper(name ="ListaImion")

i odpowiednio nazwij dla drugiej listy

0

Dzięki, działa.
Nie jest to bardzo ważne, ale zastanawia mnie jeszcze, dlaczego listy zapisują się w odwrotnej kolejności, tzn. najpierw listaCyfr, a listaImion niżej?

0

ustaw sobie nazwę parametru adnotacji na "bbb" i "aaa" i porównaj :)

0

:) Nie skojarzyłem, że listy zapisują się alfabetycznie.
Z XMLa listy pobieram w ten sposób:

public void pobierzListeZXML()
{   
   JFileChooser fileCh = new JFileChooser();

    if (fileCh.showSaveDialog(null)==JFileChooser.APPROVE_OPTION)
    {
       File nazwaPliku = fileCh.getSelectedFile();    

       try 
       {
         JAXBContext jaxbContext = JAXBContext.newInstance(Listy.class);
         Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
         Listy listy = (Listy) jaxbUnmarshaller.unmarshal(nazwaPliku);

         listaImion = (ArrayList<String>) listy.getListaImion();    
         listaCyfr = (ArrayList<Integer>) listy.getListaCyfr();

       }
       catch (JAXBException f) 
       {
          f.printStackTrace();
       }    
   }
}

Działa, ale chciałbym się upewnić, czy prawidłowo powinno się to robić w taki sposób.

0

Mógłbyś zrobić coś takiego:

    public <T> T loadDataFromFile(Class<T> inputClass, String pFilename) throws Exception {
        try (Reader reader = new FileReader(pFilename)) {
            JAXBContext jaxbContext = JAXBContext.newInstance(inputClass);
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLStreamReader xmlStream = factory.createXMLStreamReader(reader);
            JAXBElement<T> object = unmarshaller.unmarshal(xmlStream, inputClass);
            return object.getValue();
        } catch (JAXBException | XMLStreamException | IOException e) {
            throw new Exception("Invalid xml input file or error during parsing", e);
        }
    }

I wtedy mozesz sobie zrobić

Listy listy = loadDataFromFile(Listy.class, fileCh.getSelectedFile())

Wtedy obejdzie sie bez tych rzutowań.

0

Pojawia się problem, w przypadku gdybym chciał zapisać do XMLa listę pol JTextArea. Czy jest na to jakiś sposób? Na razie chodzi o przykład z rzutowaniem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0