【问题标题】:Getting all the properties with a name from a JSON and changing the value从 JSON 中获取具有名称的所有属性并更改值
【发布时间】:2019-08-02 08:17:07
【问题描述】:

我正在尝试翻译 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: &lt;em&gt;INTEGRITY OF SERVICES&lt;/em&gt;",
        "body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
    },
    {
        "_id": "a-30",
        "_parentId": "co-30",
        "_type": "article",
        "_classes": "",
        "title": "BRIBERY AND CORRUPTION",
        "displayTitle": "SECTION 03: &lt;em&gt;BRIBERY AND CORRUPTION&lt;/em&gt;",
        "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: &lt;em&gt;CONFLICTS OF INTEREST&lt;/em&gt;",
        "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: &lt;em&gt;OPERATIONAL INTEGRITY&lt;/em&gt;",
        "body": "<p>LEARN IT. OWN IT. BE IT.</p>"
    },
    {
        "_id": "a-60",
        "_parentId": "co-60",
        "_type": "article",
        "_classes": "",
        "title": "TEST YOURSELF",
        "displayTitle": "SECTION 06: &lt;em&gt;TEST YOURSELF&lt;/em&gt;",
        "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"]方式访问是不可行的,我想用翻译后的值替换现有值。

我会很感激任何线索 谢谢

【问题讨论】:

    标签: c# json json.net


    【解决方案1】:

    我修改了您的示例 JSON 以在不同级别包含“标题”:

    {
        "title": "THINK INTEGRITY AT X",
        "list": [{
                "_id": "a-10",
                "_parentId": "co-10",
                "_type": "article",
                "_classes": "",
                "title": "THINK INTEGRITY AT X",
                "displayTitle": "SECTION 01: &lt;em&gt;THINK INTEGRITY AT X &lt;/em&gt;",
                "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: &lt;em&gt;INTEGRITY OF SERVICES&lt;/em&gt;",
                "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: &lt;em&gt;INTEGRITY OF SERVICES&lt;/em&gt;",
                "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: &lt;em&gt;THINK INTEGRITY AT X &lt;/em&gt;",
                "body": "<p>ASKING THE RIGHT QUESTIONS.</p>"
            }, {
                "_id": "a-20",
                "_parentId": "co-20",
                "_type": "article",
                "_classes": "",
                "obj": {
                    "title": "replacewiththis"
                },
                "displayTitle": "SECTION 02: &lt;em&gt;INTEGRITY OF SERVICES&lt;/em&gt;",
                "body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
            }, {
                "_id": "a-20",
                "_parentId": "co-20",
                "_type": "article",
                "_classes": "",
                "obj": {
                    "obj2": {
                        "title": "replacewiththis"
                    }
                },
                "displayTitle": "SECTION 02: &lt;em&gt;INTEGRITY OF SERVICES&lt;/em&gt;",
                "body": "<p>STAYING INDEPENDENT IN ALL CIRCUMSTANCES.</p>"
            }
        ]
    }
    

    【讨论】:

      【解决方案2】:

      为避免创建类和序列化,您可以执行以下操作:

      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。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多