2014-10-23 4 views
0

Я пытаюсь создать следующий XML динамически. Это список элементов (у которых также могут быть под-списки и суб-субблицы и т. Д.).Динамическая карта и генерация XML в Groovy

<root> 
    <Fault> 
    <Code>100</Code> 
    <Type>USER</Type> 
    <DetailList> 
     <DetailText>Incorrect name</DetailText> 
     <DetailText>Incorrect ID</DetailText> 
    </DetailList> 
    <severity>ABORT</severity> 
    </Fault> 
    <Fault> 
    <Code>200</Code> 
    <Type>SYSTEM</Type> 
    <DetailList> 
     <DetailText>Invalid DB</DetailText> 
     <DetailText>Invalid Access</DetailText> 
    </DetailList> 
    <severity>CRITICAL</severity> 
    </Fault> 
</root> 

Я буду иметь доступ к источнику данных только одна строка элемента в то время, поэтому полагал, что нужно хранить данные в какой-карте. Я начал создавать динамическую карту для хранения списка элементов, которые могут быть записаны как XML, как указано в этом SO answer.

Это структура я ожидаю достижения -

def map = [ 
    ["Fault": [ 
     "Code":"100", 
     "Type":"USER", 
     "DetailList" : [ 
      ["DetailText":"Incorrect name"], 
      ["DetailText":"Incorrect ID"] 
      ], 
     "severity":"ABORT" 
     ]], 
    ["Fault": [ 
     "Code":"200", 
     "Type":"SYSTEM", 
     "DetailList" : [ 
      ["DetailText":"Invalid DB"], 
      ["DetailText":"Invalid Access"] 
      ], 
     "severity":"CRITICAL" 
     ]] 
] 

Во время выполнения, я буду получать эти значения динамически, так что сейчас это та часть, что я пытался получить работу в качестве выше -

String root = "Fault" 
String item1 = "Code" 
String item2 = "Type" 
String nextLevel = "DetailList" 
String levelItem = "DetailText" 
String innerItem1 = "Incorrect name" 
String innerItem2 = "Incorrect ID" 

def dummyMap = { [:].withDefault{ owner.call() } }() 
def map = { [:].withDefault{ owner.call() } }() 
map.put(root, [:]) 
map."$root"[item1] = "100" 
map."$root"[item2] = "USER" 
map."$root"["$nextLevel"] = [:] 
x = map."$root"["$nextLevel"] 
x."$levelItem" = innerItem1 

Здесь я застреваю. Я не могу понять, как добавить второй элемент в списке на том же уровне, не перезаписывая первый.

Я абсолютно не знаком с Groovy, поэтому я не могу делать это наилучшим образом. Если есть какой-либо другой способ, который я мог бы получить в результате XML, я был бы рад работать над вашим предложением.

+0

почему бы не использовать '[XMLSlurper] (http://groovy.codehaus.org/api/groovy/util/XmlSlurper.html)', который даст вам недвижимость как доступ к xml (такой же, как и к карте)? – cfrick

+0

также, что вы подразумеваете под '' Я буду иметь доступ к источнику данных только по одной позиции за раз ''. Это огромно или вы действительно получаете только одну строку, например. methodcall и не может накапливаться? или он просто разбит на строку и список в любом случае? – cfrick

ответ

2

Ошибка здесь:

map."$root"["$nextLevel"] = [:] 
x = map."$root"["$nextLevel"] 
x."$levelItem" = innerItem1 

Вы создаете карту ([:]) для DetailList, но, как следует из названия, вам нужен список здесь. Поэтому вам нужно будет использовать [], а затем добавить туда свои предметы. Например.

map."$root"["$nextLevel"] = [] // list! no map 
map."$root"."$nextLevel" << ["$itemLevel": item1] // add new maps at end of list 
map."$root"."$nextLevel" << ["$itemLevel": item2] // ... 

Если ваша конечная цель состоит в том, чтобы создать карту, чтобы иметь «свойство» -как доступа к коду там (например, root[0].Fault.Code), то вы можете также использовать XMLSlurper, который дал бы вам без такого Hastle что-то подобное (root.Fault[0].Code.text()).

+0

Это сработало для меня.Сначала он терпел неудачу, так как я использовал '$ levelItem' в качестве имени var, в то время как ваш образец имел' $ itemLevel', но как только я понял, это получилось здорово. – Plain

0

Если вы хотите добавить несколько элементов на карту, вы можете сделать карту карты карт, а не просто обычной. Затем, чтобы добавить второй элемент под одним и тем же ключом, вы просто привяжете его к концу массива.

Однако я бы с осторожностью применил это вручную, особенно с использованием карты - что может вызвать проблемы при попытке вытащить данные, а элементы выходят в произвольном порядке, а не в порядке которые вы их добавили. Лучше найти XML-библиотеку.

0

Если вы строите что-либо в Groovy (например, XML), вы всегда должны использовать Builder.

def builder = new groovy.xml.MarkupBuilder() 

// using your variables from above! 

def xmlRoot = builder.root { 
    "$root" { 
     "$item1"(100) 
     "$item2"("USER") 
     "$nextLevel" { 
      "$levelItem"(innerItem1) 
      "$levelItem"(innerItem2) 
     } 
     severity("ABORT") 
    } 
    // repeat as necessary 
} 

Формирует:

<root> 
    <Fault> 
    <Code>100</Code> 
    <Type>USER</Type> 
    <DetailList> 
     <DetailText>Incorrect name</DetailText> 
     <DetailText>Incorrect ID</DetailText> 
    </DetailList> 
    <severity>ABORT</severity> 
    </Fault> 
</root> 
Смежные вопросы