栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

反序列化Minecraft json的更好方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

反序列化Minecraft json的更好方法

自动化工具可能非常有用,但并不完美-尤其是在字典方面。

首先要注意的是,它们的结构都是相同的,即它们都由

hash
size
属性组成。这意味着我们可以一遍又一遍地使用相同的类,而不是创建数百个相同的类:

' the type that repeats from your robot:Public Class MinecraftItem    Public Property hash As String    Public Property size As Int32End Class

由于自动化工具在运行中(它们不会向前看…或向后看),因此他们并不真正知道它们是否相同。接下来的事情是,在这种情况下,机器人生成的类将无法工作:

Public Property minecraft/sounds/music/game/creative/creative3.ogg As _ MinecraftSoundsMusicGameCreativeCreative3Ogg

作为属性名称,这是非法的。但是,这些名称可以用作Dictionary键。除了上述

MinecraftItem
类之外,我们 可能还 需要一个容器类:

Public Class MinecraftContainer    Public objects As Dictionary(Of String, MinecraftItem)End Class

至少有3种获取数据的方法:

方法1:拔出单个项目

imports Newtonsoft.Jsonimports Newtonsoft.Json.LinqDim jstr As String = ...from whereever' parse the json into a JObjectDim js As JObject = JObject.Parse(jstr)' if you somehow know the names, you can pluck out the data:Dim mi = js("objects")("minecraft/sounds/mob/blaze/hit2.ogg")Console.WriteLine(mi("hash").ToString & "    " & mi("size").ToString)

第一行将原始json字符串解析为JObject。这使我们能够以各种方式处理内容。例如,我们可以在json中引用“对象”,并按名称引用它们,这正是下一行所发生的情况:

' drill into "objects", get the "...hit2.ogg" itemDim mi = js("objects")("minecraft/sounds/mob/blaze/hit2.ogg")

如果您只需要从大文件中获取特定的项目,这将起作用。

mi
创建的变量是“特殊” json令牌,因此请使用名称来获取所需的数据位

hash = mi("hash").ToStringsize = mi("size").ToString

方法2:反序列化为词典

这将是 我的 首选方法。包括与

import
第一个示例相同的语句,然后:

' parse the json stringDim js As JObject = JObject.Parse(jstr)' deserialize the inner "objects" to a NET DictionaryDim myItems = JsonConvert.DeserializeObject(Of Dictionary(Of String, _        MinecraftItem))(js("objects").ToString)

这将从json 创建

myItems
为Net
Dictionary(Of String,MincraftItem)
。由于
MinecraftObject
该类除了保留字典外 什么 也不做,因此我们跳过了它。

这些键是长名称,每个值都是一个

MinecraftItem
,使您可以更常规地引用它们:

' get one of the items into a variablegravel3 = myItems("minecraft/sounds/mob/chicken/step2.ogg")ConsoleWriteLine("Gravel3  hash: {0},  size: {1}",gravel3.hash, gravel3.size.ToString)

如果您不熟悉.Net字典,则它有点像数组或列表,只是您通过一个

Key
而不是索引来访问项目。要遍历它们:

Dim n As Integer = 0For Each kvp As KeyValuePair(Of String, MinecraftItem) In myItems    Console.WriteLine("Name: {0}  Hash: {1}  size: {2}",kvp.Key, kvp.Value.hash, kvp.Value.size.ToString)    n += 1    If n >= 2 Then Exit For' just print 3Next

输出:

名称:三界/郎/ de_DE.lang哈希:10a54fc66c8f479bb65c8d39c3b62265ac82e742尺寸:8112
姓名:三界/郎/ cy_GB.lang哈希:14cfb2f24e7d91dbc22a2a0e3b880d9829320243尺寸:7347
姓名:我的世界/声音/暴民/鸡肉/
step2.ogg哈希:bf7fadaf64945f6b31c803d086ac6a652aabef9b尺寸:3838

请记住,Key始终是长路径名,每个

.Value
都是
MinecraftItem
对象。

方法3:反序列化到容器

您可以使用以下

MinecraftContainer
类跳过分析步骤:

Dim jstr As String = ...from whereeverDim myJItems = JsonConvert.DeserializeObject(Of MinecraftContainer)(jstr)

请注意,这次,您将 下载的整个字符串 传递给

JsonConvert
。结果将是一个额外的外部对象,其中包含一个名为“
Objects”的字典属性。因此,您使用一些主要参考文献来引用这些项目:

gravel3hash = myJItems.Object("minecraft/sounds/dig/gravel3.ogg").hashgravel3 = myJItems.Object("minecraft/sounds/dig/gravel3.ogg")    ConsoleWriteLine("Gravel3  hash: {0},  size: {1}",gravel3.hash, gravel3.size.ToString)'or:ConsoleWriteLine("Gravel3  hash: {0},  size: {1}",        myJItems.Object("minecraft/sounds/dig/gravel3.ogg").hash,         myJItems.Object("minecraft/sounds/dig/gravel3.ogg").size.ToString)

此方法只是要反序列化的一行代码,但这意味着
a)我必须定义容器类,
b)我必须使用

myJItems.Object
钻入否则为空的容器才能获得Dictionary。

就个人而言,我会放弃使用方法2-额外增加一行代码,使其更易于使用。也就是说,您还可以从容器中提取字典集合:

Dim myItems As Dictionary(Of String, MinecraftItem)= myJItems.Object


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/430763.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号