2015-11-26 3 views
1

Мне нужно создать большой файл XML с простой структуройНаписать файл XML с внешними узлами

<file> 
<details> 
<d1></d1> 
... 
<dn></dn> 
<task></task> 
<task></task> 
... 
<task></task> 
</details> 
</file> 

Я использую JAXB для Xml - отображение POJO. Поэтому у меня есть FilePojo, у которого есть список задач. Задачи хранятся в базе данных, потому что они в больших количествах, поэтому я не могу просто восстановить их в памяти сразу.

Как я могу выполнить действие маршала?

код я до сих пор связан с этим действием, используя XMLStreamWriter

XMLOutputFactory factory = XMLOutputFactory.newInstance(); 
XMLStreamWriter xmlsw = new IndentingXMLStreamWriter(factory.createXMLStreamWriter(writerXml)); 

JAXBContext jc = JAXBContext.newInstance(File.class); 
Marshaller m = jc.createMarshaller(); 
JAXBElement<File> jx = new JAXBElement<>(new QName("http://namespace", "File"), File.class, file); 
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 

m.marshal(jx, xmlsw); 

объект Файл имеет все детали, кроме списка задач.

+0

Tricky. Не могли бы вы поделиться своим POJO для файла и как List of Tasks вписывается в это? Мое лучшее предположение заключается в том, чтобы не отображать список , а вместо этого предоставить некоторый список , который вы можете сохранить в памяти (только идентификаторы для своих задач), а затем предоставить настраиваемый маршаллер на основе XmlMapper на TaskKey для извлечения данных из БД по мере необходимости. Но это по-прежнему предполагает, что материал будет написан для каждого поля в базовом потоке, а не только в буфер, который будет возвращен после завершения всего сортировки ... – Jan

+0

@Jan У меня нет точного POJO, потому что это упрощение реальной системы , Не могли бы вы дать мне более подробную информацию, связанную с обычным маршаллером? Как это будет работать? – danidacar

ответ

1

Рассмотрите этот длинный пример (скомпилируйте и запустите - все классы включены).

В этом примере класс Details содержит два списка (не уверен, что у вас есть) - один с задачами - но без аннотаций, поэтому это не будет использоваться в JAXB, а одно с объектами TaskId, которые содержат только ссылку на один задача. Я добавил пользовательский Marshaller для объектов TaskId и сказал JAXB написать их как «задачу». Если JAXB выводит выходной сигнал, вы должны иметь возможность «загружать по одному» с помощью этого кода. Если JAXB буферизирует весь вывод, вам придется подумать о других способах генерации XML, как вы заявили, что вы не можете загружать все задачи в память.

import java.io.FileWriter; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Iterator; 
import java.util.List; 

import javax.swing.JOptionPane; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBElement; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
import javax.xml.namespace.QName; 
import javax.xml.stream.FactoryConfigurationError; 
import javax.xml.stream.XMLOutputFactory; 
import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.XMLStreamWriter; 

import my.test.XmlOut.TaskId; 
import my.test.XmlOut.TaskListAdapter; 
import my.test.XmlOut.File.Details; 
import my.test.XmlOut.File.Task; 
import my.test.XmlOut.File.TaskList; 

public class XmlOut { 
public static class TaskId { 

} 

public static class TaskListAdapter extends XmlAdapter<String,TaskId> { 

    @Override 
    public TaskId unmarshal(String v) throws Exception { 
     // TODO Auto-generated method stub 
     return null; 
    } 

    @Override 
    public String marshal(TaskId v) throws Exception { 
     //Load your actual TASK here and convert it to XML (you could use JAXB as well) 
     return "HERE GOES MY TASK XML"; 
    } 

} 

@XmlRootElement 
public static class File { 

    public static class TaskList { 
     int fileid; 

    } 

    public static class Task { 
     String id; 

     @XmlElement 
     public String getId() { 
      return id; 
     } 

     public void setId(String id) { 
      this.id = id; 
     } 
    } 

    public static class Details { 
     String d1; 
     String dn; 
     private List<Task> tasks; 
     private List<TaskId> taskIds; 

     public void setTasks(List<Task> t) { 
      tasks = t; 
     } 

     @XmlElement 
     public String getD1() { 
      return d1; 
     } 

     public void setD1(String d1) { 
      this.d1 = d1; 
     } 

     @XmlElement 
     public String getDn() { 
      return dn; 
     } 

     public void setDn(String dn) { 
      this.dn = dn; 
     } 

     @XmlElement(name="task") 
     @XmlJavaTypeAdapter(TaskListAdapter.class) 
     public List<TaskId> getTaskIds() { 
      return taskIds; 
     } 

     public void setTaskIds(List<TaskId> asList) { 
      taskIds = asList; 
     } 



    } 

    protected Details details = new Details(); 

    @XmlElement 
    public Details getDetails() { 
     return details; 
    } 

    public void setDetails(Details details) { 
     this.details = details; 
    } 
} 

public static void main(String[] args) { 
    try { 

     File file = new File(); 
     file.setDetails(new Details()); 
     file.getDetails().setD1("d1"); 
     file.getDetails().setTaskIds(Arrays.asList(new TaskId(), new TaskId(), new TaskId(), new TaskId(), 
       new TaskId(), new TaskId(), new TaskId())); 
     XMLOutputFactory factory = XMLOutputFactory.newInstance(); 

     JAXBContext jc = JAXBContext.newInstance(File.class); 
     Marshaller m = jc.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 

     JAXBElement<File> jx = new JAXBElement<>(new QName("http://namespace", "File"), File.class, file);   
     m.marshal(jx, System.out);   
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
} 
+0

Спасибо за это. Не можем ли мы определить после выполнения вашего примера, если JAXB потоки или буферизация вывода? – danidacar

+0

С просто выписыванием некоторых минимальных выходов данных не создается в TaskItem Marshaller. Но может быть внутренний буфер, который покраснет, когда будет полный.? О – Jan

Смежные вопросы