Разобрать JSON со специальным символом и массивом с помощью antlr StringTemplate
У меня есть JSON от стороннего веб-сервиса, как показано ниже:
{
"positions": {
"587007777": {
"company~": {
"industries~": [
{
"name": {
"localized": {
"en_US": "Computer Software"
}
},
"id": 4
}
]
},
"company": "urn:li:organization:2252038",
"localizedCompanyName": "Some company TEST2",
"localizedTitle": "Sr. Engineer"
},
"587008888": {
"company~": {
"industries~": [
{
"name": {
"localized": {
"en_US": "Computer Software"
}
},
"id": 4
}
]
},
"company": "urn:li:organization:2258451",
"localizedCompanyName": "Some company TEST",
"localizedTitle": "Project Manager"
}
}
}
Я использую antlr4 stringtemplate для создания текстового вывода, как показано ниже:
Positions:
position 1
Title: Sr. Engineer
Company: Some company TEST2
Industry: Computer Science
position 2
Title: Project Manager
Company: Some company TEST
Industry: Computer Science
Шаблон Antlr:
$profile.positions:{it|$if(it.localizedTitle)$
Position $i$:
$if(it.localizedTitle)$Position: $it.localizedTitle$$endif$
$if(it.localizedDescription.rawText)$Summary: $it.localizedDescription.rawText$$endif$
$if(it.startMonthYear)$Start Date: $if(it.startMonthYear.month && it.startMonthYear.year)$$it.startMonthYear.month;format="month=toString"$, $endif$$it.startMonthYear.year$$endif$
$if(it.endMonthYear)$End Date: $if(it.endMonthYear.month && it.endMonthYear.year)$$it.endMonthYear.month;format="month=toString"$, $endif$$it.endMonthYear.year$$endif$
$if(it.localizedCompanyName)$Company: $it.localizedCompanyName$$endif$
Industry:$it.company~.industries~:{it|$if(it.name.localized.en_US)$
$if(it.name.localized.en_US)$ind: $it.name.localized.en_US$$endif$
$endif$}$
$endif$}$
Код C#:
string[] _arrayPropertyNames=new string[] {"skills","positions", "industries~" };
public object GetProperty(Interpreter interpreter, TemplateFrame frame, object obj, object property, string propertyName)
{
Dictionary<string, object> dictionary = obj as Dictionary<string, object>;
if (dictionary == null)
{
throw new Exception("Can not convert parameters to dictionary");
}
try
{
Debug.WriteLine("=> properyname={0}, property={1} obj={2}", propertyName, property,
string.Join(",\r\n -> ", dictionary.Select(m => m.Key + ":" + m.Value).ToArray()));
}
catch { }
object resp = dictionary.ContainsKey(propertyName) ? dictionary[propertyName] : null;
if (resp is JObject)
{
if (_arrayPropertyNames.Contains(property)) // I want to avoid this check
return
((JObject) resp).Children()
.Select(item => item.First().ToObject<Dictionary<string, object>>())
.ToList();
return JObject.FromObject(resp).ToObject<IDictionary<string, object>>();
}
JArray jArrayResponse = resp as JArray;
if (jArrayResponse != null)
{
if (jArrayResponse.Count == 0) return null;
List<JObject> elements = jArrayResponse.Children().OfType<JObject>().ToList();
if (elements.Any())
{
return elements.Select(item => item.ToObject<Dictionary<string, object>>()).ToList();
}
return jArrayResponse.Children().Select(item => item.Value<string>()).ToList();
}
return (resp != null && string.IsNullOrEmpty(resp.ToString())) ? null : resp;
}
Я пытаюсь получить строку вывода с помощью antlr4, и у меня есть две проблемы:
- Позиции имеют тип массива, но в другом формате (так как они не имеют большой скобки). В коде я пытаюсь проверить, является ли элемент JSON JObject или JArray. Так как позиции имеют тип массива, я ожидал, что это будет JArray, но на самом деле это просто JObject. Итак, я должен поддерживать список _arrayPropertyNames для хранения списка имен свойств типа массив типа и обрабатывать его, чтобы получить дочерние элементы. Я хочу избежать этого жесткого кода и получить общее решение.
- Второй - это JSON, содержащий имя свойства "company~", которое имеет ~ в конце. И есть еще одно свойство, имя которого просто "company" по тому же пути, но нам просто нужно получить отраслевое имя из элемента "company~", поэтому в шаблоне antlr4 мы определили, как указано выше. Но мы получаем просто "company" в propertyName в методе GetProperty, но словарь (obj) содержит "company~" в качестве ключа, поэтому не может извлечь отрасль.