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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.