Как генерировать XML динамически с SimpleXml и Java? Элементы, ElementList должен динамически появляться в случайной позиции - PullRequest
2 голосов
/ 11 ноября 2011

При создании файлов XML с помощью SimpleXml у меня возникла сложная проблема.

Я хочу сделать динамический вывод XML следующим образом.

<process>
<sequence> ... </sequence>
<flow> ... </flow>
<sequence> ... </sequence>
<flow> ... </flow>
</process>

Вопрос в том, как я могу определить в схеме, используя SimpleXMl?

Теперь это выглядит так

@Root
public class Process {


    @ElementList(inline=true, required = false)
    private List<Sequences> sequence;

    @ElementList(inline=true, required = false)
    private List<Flows> flow;
    }

Согласно этой схеме он всегда генерирует XML в следующем формате:

<process>
<sequence> ... </sequence>
<sequence> ... </sequence>
<flow> ... </flow>
<flow> ... </flow>
</process>

Что мне делать? Спасибо.

1 Ответ

2 голосов
/ 11 ноября 2011

Вот как вам нужно использовать из документации:

http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#scatter

Удачи.


Рассеяние записей встроенных элементов

Элементы, которые разбросаны по всему документу XML, можно собирать с помощью встроенных списков и встроенных карт. Просто укажите имя записи для имени элемента XML, который должен собирать список или карта, и они будут извлечены и помещены в объект коллекции. Например, возьмите следующий элемент XML. Он содержит элементы include и exclude XML, которые не имеют определенного порядка. Даже если они не в каком порядке, процесс десериализации может собирать элементы XML при их обнаружении.

<fileSet path="/user/niall">
   <include pattern=".*.jar"/>
   <exclude pattern=".*.bak"/>
   <exclude pattern="~.*"/>
   <include pattern=".*.class"/>
   <exclude pattern="images/.*"/>
</fileSet>

Для достижения этой цели можно использовать следующий объект. Это объявляет две встроенные коллекции, которые определяют имя объектов записи, которые они собирают. Если атрибут entry не указан, вместо него будет использоваться имя объекта.

@Root
public class FileSet {

   @ElementList(entry="include", inline=true)
   private List<Match> include;

   @ElementList(entry="exclude", inline=true)
   private List<Match> exclude;

   @Attribute
   private File path;

   private List<File> files;

   public FileSet() {
      this.files = new ArrayList<File>();
   }

   @Commit
   public void commit() {
      scan(path);
   }

   private void scan(File path) { 
      File[] list = path.listFiles();

      for(File file : list) {
         if(file.isDirectory()) {
            scan(path);
         } else {            
            if(matches(file)) {
               files.add(file);
            }
         }
      }
   }

   private boolean matches(File file) {
      for(Match match : exclude) {
         if(match.matches(file)) {
            return false;
         }
      }
      for(Match match : include) {
         if(match.matches(file)) {
            return true;
         }
      }
      return false;
   }

   public List<File> getFiles() {
      return files;
   }

   @Root
   private static class Match {

      @Attribute            
      private String pattern;            

      public boolean matches(File file) {
         Stirng path = file.getPath();

         if(!file.isFile()) {
            return false;
         }
         return path.matches(pattern);         
      }         
   }
}
...