首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从JSON获取具有名称的所有属性并更改值

从JSON获取具有名称的所有属性并更改值
EN

Stack Overflow用户
提问于 2019-08-02 16:17:07
回答 2查看 1.1K关注 0票数 0

我正在尝试翻译JSON文档的内容。这意味着我必须转换某些属性的值,而不是全部。

为了隔离这个问题,我试图获取具有特定名称(例如title )的所有属性,这些属性可能位于不同的json级别,然后获取这些属性的值,使用翻译服务转换该值,并用转换后的值替换回每个属性的值。

如何使用C#实现这一点?我正在尝试使用Newtonsoft.Json库,JToken、JProperty的用法对我来说有点混乱。

以下是json文件的示例:

代码语言:javascript
复制
[
    {
        "_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“属性的内容,可以是这样的:

代码语言:javascript
复制
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“方式访问是不可行的,我想用翻译后的值替换现有的值。

我很感谢任何线索谢谢

EN

回答 2

Stack Overflow用户

发布于 2019-08-02 22:01:05

我修改了你的示例JSON,在不同的级别包含了"title“:

代码语言:javascript
复制
{
    "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#中找到):

代码语言:javascript
复制
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);
            }
        }
    }
}

产生以下结果:

代码语言:javascript
复制
{
    "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>"
        }
    ]
}
票数 1
EN

Stack Overflow用户

发布于 2019-08-02 16:51:41

为了避免创建类和序列化,您可以这样做:

代码语言:javascript
复制
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。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57322438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档