Groovy MarkupBuilder передает строку по ссылке
Выполнение преобразования канала JSON в формат, который может использоваться нашим экземпляром Endeca, и остановился на написании этого преобразования в Groovy благодаря таким инструментам, как JsonSlurper и MarkupBuilder. Наш ввод фида JSON выглядит следующим образом (сохранен как stage/newObject.json):
[
{
"Name": "Object Name",
"DimID": 0000,
"ObjectID": "Object-0000",
"TypeID": 1,
"Type": "Object Type",
"Description": "A Description",
"DirectorID": "007",
"DirectorName": "Bond, James",
"ParentObjectID": null,
"ObjectLevelID": 1,
"ObjectLevel": "MI-6",
"ProjectNumbers": [
"0001",
"0002"
],
"ManagerIDs": [
"001"
],
"ManagerNames": [
"M"
],
"SubObjectIDs": [
"006",
"005"
],
"TaskNumbers": [
"001"
],
"ProjectNames": [
"Casino Royal",
"Goldfinger",
"License to Kill"
]
}
]
И код, который я должен сделать для преобразования:
def rawJSONFile = new File("stage/newObject.json")
JsonSlurper slurper = new JsonSlurper()
def slurpedJSON = slurper.parseText(rawJSONFile.text)
def xmlOutput = new MarkupBuilder(new FileWriter(new File("stage/ProcessedOutput.xml")))
xmlOutput.RECORDS() {
for (object in slurpedJSON) {
RECORD() {
for (field in object) {
if (field.value != null) {
if (field.value.value.class.equals(java.util.ArrayList)) {
if (field.value.value.size > 0) {
for (subField in field.value.value) {
if (subField != null) {
PROP(NAME: field.key) {
PVAL(subField)
}
}
}
}
} else {
PROP(NAME: field.key) {
PVAL(field.value)
}
}
}
}
}
}
}
Проблема, с которой мы сталкиваемся, находится примерно на полпути вниз по скрипту groovy, где он имеет дело с подполями (то есть массивами в JSON), замыкание, создающее узел "PVAL", передает переменную subField по ссылке, и это не будучи обработанным как строка, но как массив символов, поэтому, пытаясь сделать вывод, мы получаем расположение в памяти, а не строку. Обходной путь, который у нас есть, заключается в следующем, но я хотел знать, было ли более элегантное решение:
for (subField in field.value.value) {
if (subField != null) {
PROP(NAME: field.key) {
StringBuilder subFieldValue = new StringBuilder();
for(int i =0; i<subField.length; i++){
subFieldValue.append(subField[i])
}
PVAL(subFieldValue.toString())
}
}
}
1 ответ
+ Изменить subField in field.value.value
в subField in field.value
в
for (subField in field.value) {
if (subField != null) {
PROP(NAME: field.key) {
PVAL(subField)
}
}
}
Хотя эта логика может быть упрощена как
xmlOutput.RECORDS {
slurpedJSON.each { map ->
Record {
map.each { k, v ->
if ( v in ArrayList ) {
v.each { val ->
PROP(NAME: k) {
PVAL(val)
}
}
} else {
PROP(NAME: k) {
PVAL(v)
}
}
}
}
}
}