Создать XML на основе иерархии классов

Мой код выглядит следующим образом:

class GlobalInfo {
    // multiple properties here
    String name;
    GlobalInfo parent;
    static hasMany = [children: GlobalInfo]
}

class RegionalInfo extends GlobalInfo {
    // multiple properties here
}

class BankInfo extends GlobalInfo {
    // multiple properties here
}

Может быть несколько BankInfo в одном RegionalInfo. И может быть несколько родителей RegionalInfo внутри объекта BankInfo.

Например,

BankInfo == Bank Of America

RegionalInfo == Dallas // 1st parent

RegionalInfo == Texas // Dallas's parent

RegionalInfo == MidWest // Texas's parent and final parent.

В приведенном выше примере непосредственный родительский объект объекта BankInfo указывает на Даллас, а его родительский указывает на Техас, а затем его родительский указывает на MidWest.

В некоторых случаях может быть только один или два родителя

Например,

BankInfo == University Credit Union

RegionalInfo == Houston

Например, представление иерархии классов от самого верхнего родительского элемента будет выглядеть примерно так: Это всего лишь пример, и я могу получить любую комбинацию.

<MidWest>
   <Independent Bank Of MidWest/>
   <Midland Bank Of America/>
   <Texas>
      <Bank Of America>
      <Austin>
         <Supereme National Bank>
         <Master Chanse Bank>
         <Austin East>
            <National Bank Of Austin>
            <Federal Bank>
         </Austin East>
      </Austin>
   </Texas>
   <Kansas>
      <Federal Credit Union>
      <Kansas State Bank>
   </Kansas>
</MidWest>

Места являются объектами RegionalInfo, а банки - объектами BankInfo.

Проблема здесь в том, что, как вы видите, существует возможность большего количества объектов RegionalInfo внутри одного объекта RegionalInfo.

Ниже приведен код, который я придумал.

def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.root(name: "MidWest"){
    bank(name: "Independent Bank Of MidWest")
    bank(name: "Midland Bank Of America")
    location(name: "Texas", expanded: true){
        reader(name:"Bank Of America")
        location(name: "Austin", expanded: true){
            bank(name:"Supereme National Bank")
            bank(name:"Master Chanse Bank")
                location(name: "Austin East", expanded: true){
                    bank(name:"National Bank Of Austin")
                    bank(name:"Federal Bank")
                }
        }
    }
    location(name: "Kansas", expanded: true){
        bank(name:"Federal Credit Union")
        bank(name:"Kansas State Bank")
    }
}

Проблема здесь в том, что все создано статически. Я хочу создать XML динамически, потому что структура объекта класса будет меняться каждый раз.

Возможно ли это сделать?

Целью создания этого XML является использование этого в плагине TreeView для рисования структуры иерархии классов от самого верхнего родительского элемента. В приведенном выше примере самый верхний родитель - MidWest.

ОБНОВЛЕНО

XML сгенерирован для кода выше:

<root name='MidWest'>
  <bank name='Independent Bank Of MidWest' />
  <bank name='Midland Bank Of America' />
  <location name='Texas' expanded='true'>
    <bank name='Bank Of America' />
    <location name='Austin' expanded='true'>
      <bank name='Supereme National Bank' />
      <bank name='Master Chanse Bank' />
      <location name='Austin East' expanded='true'>
        <bank name='National Bank Of Austin' />
        <bank name='Federal Bank' />
      </location>
    </location>
  </location>
  <location name='Kansas' expanded='true'>
    <bank name='Federal Credit Union' />
    <bank name='Kansas State Bank' />
  </location>
</root>

1 ответ

Решение

Как-то так (я адаптировал классы, чтобы иметь возможность запускать их автономно, удалив hasMany)?

import groovy.xml.MarkupBuilder

class GlobalInfo {
    String name
    GlobalInfo parent
    List<GlobalInfo> children
}

class RegionalInfo extends GlobalInfo {
    // multiple properties here

}

class BankInfo extends GlobalInfo {
    // multiple properties here

}


String root(GlobalInfo root) {
    def out = new StringWriter()
    MarkupBuilder xml = new MarkupBuilder(out)
    xml.root(name: root.name) {
        root.children.each {
            child(xml, it)
        }
    }
    out.toString()
}


void child(MarkupBuilder xml, RegionalInfo info) {
    xml.location(makeAttributes(info)) {
        info.children?.each { child(xml, it) }
    }
}

void child(MarkupBuilder xml, GlobalInfo info) {
    throw new RuntimeException("GlobalInfo not expected here")
}

void child(MarkupBuilder xml, BankInfo info) {
    xml.bank(makeAttributes(info))
}

protected LinkedHashMap<String, String> makeAttributes(GlobalInfo info) {
    def attrs = [
            name: info.name
    ]
    if (info.children) {
        attrs.expanded = true
    }
    attrs
}

def midwest = new GlobalInfo(
        name: "MidWest",
        children: [
                new BankInfo(
                        name: 'Independent Bank Of MidWest'
                ),
                new RegionalInfo(
                        name: 'Texas',
                        children: [
                                new BankInfo(
                                        name: 'Bank Of America'
                                ),
                                new RegionalInfo(
                                        name: 'Austin',
                                        children: [
                                                new BankInfo(
                                                        name: 'National Bank Of Austin'
                                                )
                                        ]
                                )
                        ]
                )
        ]
)

println root(midwest)

в результате чего:

<root name='MidWest'>
  <bank name='Independent Bank Of MidWest' />
  <location name='Texas' expanded='true'>
    <bank name='Bank Of America' />
    <location name='Austin' expanded='true'>
      <bank name='National Bank Of Austin' />
    </location>
  </location>
</root>
Другие вопросы по тегам