首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JObject.SelectToken等价于.NET

JObject.SelectToken等价于.NET
EN

Stack Overflow用户
提问于 2016-04-10 10:58:27
回答 1查看 829关注 0票数 1

我需要删除JSON的外部节点。例如:

代码语言:javascript
复制
{
    app: {
       ...
    }
}

任何关于如何移除外部节点的想法,所以我们只得到

代码语言:javascript
复制
{
   ...
}

不使用使用JSON.NET,只有.NET框架(C#)中的工具。

在Json.NET中,我使用了:

代码语言:javascript
复制
JObject.Parse(json).SelectToken("app").ToString();

或者,DataContractJsonSerializer的任何配置(使其在反序列化时忽略根)也会工作。我现在进行反犯罪的方式是:

代码语言:javascript
复制
protected T DeserializeJsonString<T>(string jsonString)
        {
            T tempObject = default(T);

            using (var memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
            {
                var serializer = new DataContractJsonSerializer(typeof(T));
                tempObject = (T)serializer.ReadObject(memoryStream);
            }

            return tempObject;
        }

请注意,根对象的属性名称可能因情况不同而有所不同。例如,它可以是"transaction"

谢谢你的建议。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-10 17:32:30

不存在与SelectToken内置到.Net中的等效。但是,如果您只是想打开外部根节点,而不预先知道节点名称,则有以下选项。

  1. 如果使用的是.Net 4.5或更高版本,则可以使用DataContractJsonSerializer.UseSimpleDictionaryFormat = true将其反序列化为Dictionary<string, T>: 受保护的T MemoryStream(Encoding.Unicode.GetBytes(jsonString))) (String jsonString) { var (var memoryStream =新的jsonString memoryStream=新的jsonString T>);serializer.UseSimpleDictionaryFormat = true;var字典= (Dictionary)serializer.ReadObject(memoryStream);if (字典== null = dictionary.Count dictionary.Count == 0)返回默认值(T);否则,如果(dictionary.Count == 1)返回dictionary.Values.Single();否则{抛出新的InvalidOperationException(“根对象有太多属性”);}} 注意,如果根对象包含多个属性,则不能反序列化为Dictionary以获得第一个属性,因为该类中项的顺序未定义。
  2. 在任何支持数据契约序列化器的.Net版本上,您都可以利用DataContractJsonSerializerXmlObjectSerializer继承来调用JsonReaderWriterFactory.CreateJsonReader()来创建实际读取JSON的XmlReader这一事实,然后跳到第一个嵌套的“元素”: 受保护的T DeserializeNestedJsonStringWithReader(string jsonString) { var System.Xml.XmlDictionaryReaderQuotas.Max=System.Xml.XmlDictionaryReaderQuotas.Max;int elementCount = 0;while (reader.Read()) { if (reader.NodeType == System.Xml.XmlNodeType.Element) elementCount++;if (elementCount == 2) // At elementCount == 1有一个合成的"root“元素{ var序列化器=新DataContractJsonSerializer(typeof(T));返回(T)serializer.ReadObject(读取器,false);}返回默认值(T);} 这种技术看起来很奇怪(用XmlReader解析JSON?),但是通过一些额外的工作,应该可以扩展这个想法,为类似于JSON的JSON创建SAX类解析功能,跳过JSON,直到找到所需的属性,然后反序列化它的值。 例如,要选择和反序列化特定的命名属性,而不仅仅是第一个根属性,可以使用以下内容: 公共静态类DataContractJsonSerializerExtensions {公共静态T DeserializeNestedJsonProperty(string jsonString,string rootPropertyName) { //检查计数== 2,因为顶部有一个合成元素。Predicate match =s => s.Count == 2 && s.Peek() == rootPropertyName;返回DeserializeNestedJsonProperties(jsonString,match).FirstOrDefault();}公共静态IEnumerable DeserializeNestedJsonProperties(string jsonString,Predicate match) { DataContractJsonSerializer序列化器= null;使用(var reader =s.Peek XmlDictionaryReaderQuotas.Max){ var堆栈=新堆栈();时间(reader.Read()) { if (reader.NodeType == System.Xml.XmlNodeType.Element) { stack.Push(reader.Name);if (匹配(堆栈)){序列化程序=序列化程序?新DataContractJsonSerializer(类型(T));屈服返回(T)serializer.ReadObject(读取器,假);} if (reader.IsEmptyElement) stack.Pop();}否则if (reader.NodeType == XmlNodeType.EndElement) { stack.Pop();} 有关JSON与XML之间的映射如何将JSON映射到JsonReaderWriterFactory的详细信息,请参阅JsonReaderWriterFactory
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36528849

复制
相关文章

相似问题

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