json - 当json有多个级别时将Json转换为Datatable
问题描述
在我的程序中,这是我第一次尝试解析 JSON 内容。
我试图得到的结果是一个带有如下列的 DataTable:
| Text of group | Text of Item | Command of Item |
JSON如下:
{
"Groups": [
{
"Items": [
{
"Command": "Framework.Windows.Components.ESScrollerForm, ESGrid|SHOW|Χρήστες|ESGOUser|ESGOUser_def|||65535",
"Key": "834888dd-c4d5-449a-96b7-67db5c3d2692",
"Text": "Users",
"ImageIndex": -1
},
{
"Command": "Framework.Windows.Components.ESScrollerForm, ESGrid|SHOW|QuestionaireSurveyorQuery|ESTMTask|QuestionaireSurveyorQuery|||0",
"Key": "b71de66d-2baf-4452-ada7-8fc67044876b",
"Text": "QuestionaireSurveyorQuery"
}
],
"Expanded": true,
"Tag": "",
"Key": "b741e67a-a3cd-4b97-91cf-ae9c9d9db7d7",
"Text": "Settings",
"ImageIndex": -1
},
{
"Items": [
{
"64String": "Soap",
"Command": "cInvoke|Booked Requests Agent Booking|SHOW|ESMIS|BookedReqAgentBook||False",
"Key": "bfbc3d4a-ef8a-49a0-918a-331813ba90fb",
"Text": "Requests Agent Booking",
"ImageIndex": -1
},
{
"64String": "Jrse",
"Command": "cInvoke|HHG SF Profit \u0026 Loss|SHOW|ESMIS|HHGFileProfitability||False",
"Key": "cf1cbffc-aba9-4e0f-8d6c-ba7219932fb6",
"Text": "HHG SF Profit \u0026\u0026 Loss",
"ImageIndex": -1
}
],
"Tag": "..CSShortcuts\\HHGReporting.ebl",
"Key": "eff0d713-a70e-4582-a103-b8cc5cecdad6",
"Text": "HHGReporting",
"ImageIndex": -1
}
]
}
过去,我使用 成功解析了复杂的 XML XPATH
,但现在使用 Newtonsoft.Json 时遇到了很多困难,但没有成功。
我尝试过的是首先使用在线生成器创建 3 个类:
Public Class Rootobject
Public Property Groups() As Group
End Class
Public Class Group
Public Property Items() As Item
Public Property Expanded As Boolean
Public Property Tag As String
Public Property Key As String
Public Property Text As String
Public Property ImageIndex As Integer
End Class
Public Class Item
Public Property Command As String
Public Property Key As String
Public Property Text As String
Public Property ImageIndex As Integer
Public Property 64String As String
End Class
任何想法应该如何反序列化命令,以便将数据作为具有描述结构的 DataTable 获取?
解决方案
您有一个几乎是工人阶级的模型,需要进行一些更改才能使其按预期工作。
这种语法具有误导性:
Public Property Groups() As Group
这不是对象的集合,它只是 Type 的单个对象Group
。
全部更改为:
Public Property Groups As Group()
'or
Public Property Groups As List(Of Group)
要转换为具有特定列选择的 DataTable,您需要迭代 Groups 集合,并且对于每个组,迭代 Items 集合,以提取您需要的值。
在这里,我使用了一个专门的类,GroupsHandler
它包含用于反序列化兼容 JSON 并将结果数据结构的部分内容转换为 DataTable 的类 Model。
该类GroupsHandler
公开了两个公共方法:
Deserialize()
,用于将 JSON 内容转换为 .Net 类ToDataTable()
,用于从反序列化的内容创建 DataTable。
您可以初始化处理程序并将这些方法称为:
Dim handler = New GroupsHandler(Json)
' Only deserialize
Dim myGroups = handler.Deserialize()
' Deserialize and convert to DataTable
Dim dt = handler.ToDataTable()
类名在Group
中更改ItemsGroup
,因为Group
是语言关键字。属性名称在 中更改
,因为您不能拥有以数字开头的属性名称。64String
String64
Imports Newtonsoft.Json
Public Class GroupsHandler
Private root As GroupsRoot = Nothing
Private m_json As String = String.Empty
Public Sub New(json As String)
m_json = json
End Sub
Public Function Deserialize() As List(Of ItemsGroup)
root = JsonConvert.DeserializeObject(Of GroupsRoot)(m_json)
Return root.Groups
End Function
Public Function ToDataTable() As DataTable
If root Is Nothing Then
If String.IsNullOrEmpty(m_json) Then Return Nothing
Deserialize()
End If
Dim dt As New DataTable("Groups")
dt.Columns.AddRange(New DataColumn() {
New DataColumn("GroupText", GetType(String)),
New DataColumn("ItemText", GetType(String)),
New DataColumn("ItemCommand", GetType(String))
})
For Each grp In root.Groups
For Each item In grp.Items
dt.Rows.Add(New Object() {grp.Text, item.Text, item.Command})
Next
Next
Return dt
End Function
Public Class GroupsRoot
Public Property Groups As List(Of ItemsGroup)
End Class
Public Class ItemsGroup
Public Property Items As List(Of Item)
<JsonProperty("Expanded", NullValueHandling:=NullValueHandling.Ignore)>
Public Property Expanded As Boolean?
Public Property Tag As String
Public Property Key As Guid
Public Property Text As String
Public Property ImageIndex As Long
End Class
Public Class Item
Public Property Command As String
Public Property Key As Guid
Public Property Text As String
<JsonProperty("ImageIndex", NullValueHandling:=NullValueHandling.Ignore)>
Public Property ImageIndex As Long?
<JsonProperty("64String", NullValueHandling:=NullValueHandling.Ignore)>
Public Property String64 As String
End Class
End Class
推荐阅读
- javascript - 在javascript中停止日期到纪元转换
- keycloak - Keycloak:从“编辑帐户”页面更新自定义用户属性
- python - spark XGBoostClassifier 包中是否有参数,例如 Python XGBoost fit() 函数中的“subsample_weight”?
- angular - 为什么在 for 循环中未定义使用 ngModel 的模板引用变量?
- .net - 无需额外先决条件的自定义操作
- python - 从凌乱的 JSON 文件中读取并使用 pandas 写入 excel
- c# - 如何获取PC的本地IP?
- html - 在 svg 文件上悬停更改颜色
- html - 两个类的引导 CSS
- javascript - 用于转到上一页的“alt+left”不适用于 testcafe,但手动可以正常工作