我正在尝试翻译JSON文档的内容。这意味着我必须转换某些属性的值,而不是全部。
为了隔离这个问题,我试图获取具有特定名称(例如title )的所有属性,这些属性可能位于不同的json级别,然后获取这些属性的值,使用翻译服务转换该值,并用转换后的值替换回每个属性的值。
如何使用C#实现这一点?我正在尝试使用Newtonsoft.Json库,JToken、JProperty的用法对我来说有点混乱。
以下是json文件的示例:
[
{
"_id": "a-10",
"_parentId": "co-10",
"_type": "article",
"_classes": "",
"title": "THINK INTEGRITY AT X",
"displayTitle": "SECTION 01: <em>THINK INTEGRITY AT X </em>",
"body": "<p>ASKING THE RIGHT QUESTIONS.</p>"
},
{
"_id": "a-20",
"_parentId": "co-20",
"_type": "article",
"_classes": "",
"title": "INTEGRITY OF SERVICES",
"displayTitle": "SECTION 02: <em>INTEGRITY OF SERVICES</em>",
"body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
},
{
"_id": "a-30",
"_parentId": "co-30",
"_type": "article",
"_classes": "",
"title": "BRIBERY AND CORRUPTION",
"displayTitle": "SECTION 03: <em>BRIBERY AND CORRUPTION</em>",
"body": "<p>KNOWING WHAT YOU SHOULD AND SHOULDN'T ACCEPT.</p>"
},
{
"_id": "a-40",
"_parentId": "co-40",
"_type": "article",
"_classes": "",
"title": "CONFLICTS OF INTEREST",
"displayTitle": "SECTION 04: <em>CONFLICTS OF INTEREST</em>",
"body": "<p>RECOGNISING CONFLICTS AND KNOWING WHAT TO DO.</p>"
},
{
"_id": "a-50",
"_parentId": "co-50",
"_type": "article",
"_classes": "",
"title": "OPERATIONAL INTEGRITY",
"displayTitle": "SECTION 05: <em>OPERATIONAL INTEGRITY</em>",
"body": "<p>LEARN IT. OWN IT. BE IT.</p>"
},
{
"_id": "a-60",
"_parentId": "co-60",
"_type": "article",
"_classes": "",
"title": "TEST YOURSELF",
"displayTitle": "SECTION 06: <em>TEST YOURSELF</em>",
"body": "<p>PUTTING YOUR INTEGRITY TO THE TEST.</p>"
}
]所以要翻译所有json中的"title“属性的内容,可以是这样的:
string jsonText = File.ReadAllText(jsonfilename);
JArray jsonDocument = JArray.Parse(jsonText);
IEnumerable<JToken> titles = jsonDocument.SelectTokens("..title");
foreach (var title in titles)
{
string translatedText = TranslationService.TranslateString(title.ToString(), fromlanguage, tolanguage, "text/plain");
title.Replace(JToken.FromObject(new { title = translatedText }));
}但是这不起作用,我想我已经接近了,但是我看不到用翻译后的属性值替换属性值的方法。
请记住,标题可以在JSON文件中的任何级别,因此使用jsonDocument" title“方式访问是不可行的,我想用翻译后的值替换现有的值。
我很感谢任何线索谢谢
发布于 2019-08-02 22:01:05
我修改了你的示例JSON,在不同的级别包含了"title“:
{
"title": "THINK INTEGRITY AT X",
"list": [{
"_id": "a-10",
"_parentId": "co-10",
"_type": "article",
"_classes": "",
"title": "THINK INTEGRITY AT X",
"displayTitle": "SECTION 01: <em>THINK INTEGRITY AT X </em>",
"body": "<p>ASKING THE RIGHT QUESTIONS.</p>"
}, {
"_id": "a-20",
"_parentId": "co-20",
"_type": "article",
"_classes": "",
"obj": {
"title": "THINK INTEGRITY AT X"
},
"displayTitle": "SECTION 02: <em>INTEGRITY OF SERVICES</em>",
"body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
},
{
"_id": "a-20",
"_parentId": "co-20",
"_type": "article",
"_classes": "",
"obj": {
"obj2": {
"title": "THINK INTEGRITY AT X"
}
},
"displayTitle": "SECTION 02: <em>INTEGRITY OF SERVICES</em>",
"body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
}
]
}然后使用以下代码(可在Deep find or search the key at any level in JSON and replace its value in c#中找到):
static void Main(string[] args)
{
string jsonText = File.ReadAllText(jsonfilename);
var jToken = JToken.Parse(jsonText);
var replaced = FindAndReplace(jToken, "title", "replacewiththis");
var final = replaced.ToString(Formatting.Indented);
Console.ReadLine();
}
public static JToken FindAndReplace(JToken jToken, string key, JToken value, int? occurence = null)
{
var searchedTokens = jToken.FindTokens(key);
int count = searchedTokens.Count;
if (count == 0)
return $"The key you have to search is not present in json, Key: {key}";
foreach (JToken token in searchedTokens)
{
if (!occurence.HasValue)
jToken.SetByPath(token.Path, value);
else
if (occurence.Value == searchedTokens.IndexOf(token))
jToken.SetByPath(token.Path, value);
}
return jToken;
}
public static class JsonExtensions
{
public static void SetByPath(this JToken obj, string path, JToken value)
{
JToken token = obj.SelectToken(path);
token.Replace(value);
}
public static List<JToken> FindTokens(this JToken containerToken, string name)
{
List<JToken> matches = new List<JToken>();
FindTokens(containerToken, name, matches);
return matches;
}
private static void FindTokens(JToken containerToken, string name, List<JToken> matches)
{
if (containerToken.Type == JTokenType.Object)
{
foreach (JProperty child in containerToken.Children<JProperty>())
{
if (child.Name == name)
{
matches.Add(child.Value);
}
FindTokens(child.Value, name, matches);
}
}
else if (containerToken.Type == JTokenType.Array)
{
foreach (JToken child in containerToken.Children())
{
FindTokens(child, name, matches);
}
}
}
}产生以下结果:
{
"title": "replacewiththis",
"list": [{
"_id": "a-10",
"_parentId": "co-10",
"_type": "article",
"_classes": "",
"title": "replacewiththis",
"displayTitle": "SECTION 01: <em>THINK INTEGRITY AT X </em>",
"body": "<p>ASKING THE RIGHT QUESTIONS.</p>"
}, {
"_id": "a-20",
"_parentId": "co-20",
"_type": "article",
"_classes": "",
"obj": {
"title": "replacewiththis"
},
"displayTitle": "SECTION 02: <em>INTEGRITY OF SERVICES</em>",
"body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
}, {
"_id": "a-20",
"_parentId": "co-20",
"_type": "article",
"_classes": "",
"obj": {
"obj2": {
"title": "replacewiththis"
}
},
"displayTitle": "SECTION 02: <em>INTEGRITY OF SERVICES</em>",
"body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
}
]
}发布于 2019-08-02 16:51:41
为了避免创建类和序列化,您可以这样做:
JArray jsonDocument = JArray.Parse(json);
foreach(var token in jsonDocument)
{
var obj = token.Value<JObject>();
obj["title"] = TranslationService.TranslateString(title.ToString(), fromlanguage, tolanguage, "text/plain");
}然后你需要保存你的jsonDocument。
https://stackoverflow.com/questions/57322438
复制相似问题