当 json 有多个级别时,将 Json 转换为数据表
Convert Json to Datatable when json has multiple levels
在我的程序中,这是我第一次尝试解析 JSON 内容。
我试图获得的结果是一个包含如下列的数据表:
| 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
}
]
}
过去,我使用 XPATH
成功解析了复杂的 XML,但现在我使用 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 获取?
您有一个几乎可以工作的 class 模型,需要进行一些更改才能使其按预期工作。
这种语法具有误导性:
Public Property Groups() As Group
这不是对象的集合,它只是类型 Group
的单个对象。
全部改为:
Public Property Groups As Group()
'or
Public Property Groups As List(Of Group)
要转换为具有特定列选择的 DataTable,您需要迭代 Groups 集合,并针对每个组迭代 Items 集合,以提取您需要的值。
在这里,我使用了一个专门的 class、GroupsHandler
,其中包含用于反序列化兼容 JSON 并将结果数据的部分内容转换为 DataTable 的 class 模型结构。
GroupsHandler
class公开了两个Public方法:
Deserialize()
,用于转换为.Net classes JSON内容
ToDataTable()
,用于从反序列化的内容创建数据表。
您可以初始化处理程序并调用这些方法:
Dim handler = New GroupsHandler(Json)
' Only deserialize
Dim myGroups = handler.Deserialize()
' Deserialize and convert to DataTable
Dim dt = handler.ToDataTable()
Group
class 名称在 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
在我的程序中,这是我第一次尝试解析 JSON 内容。
我试图获得的结果是一个包含如下列的数据表:
| 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
}
]
}
过去,我使用 XPATH
成功解析了复杂的 XML,但现在我使用 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 获取?
您有一个几乎可以工作的 class 模型,需要进行一些更改才能使其按预期工作。
这种语法具有误导性:
Public Property Groups() As Group
这不是对象的集合,它只是类型 Group
的单个对象。
全部改为:
Public Property Groups As Group()
'or
Public Property Groups As List(Of Group)
要转换为具有特定列选择的 DataTable,您需要迭代 Groups 集合,并针对每个组迭代 Items 集合,以提取您需要的值。
在这里,我使用了一个专门的 class、GroupsHandler
,其中包含用于反序列化兼容 JSON 并将结果数据的部分内容转换为 DataTable 的 class 模型结构。
GroupsHandler
class公开了两个Public方法:
Deserialize()
,用于转换为.Net classes JSON内容ToDataTable()
,用于从反序列化的内容创建数据表。
您可以初始化处理程序并调用这些方法:
Dim handler = New GroupsHandler(Json)
' Only deserialize
Dim myGroups = handler.Deserialize()
' Deserialize and convert to DataTable
Dim dt = handler.ToDataTable()
Group
class 名称在 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