使用 CHOETL 将 JSON 转换为 CSV,获取的不仅仅是 JSON 数组中的第一项
Getting more then just the first item in JSON array using CHOETL converting JSON to CSV
一直在努力解决以下问题:我收到来自我们电子商务网站 (Shopify) 的订单的 JSON 响应。我需要根据响应创建 CSV。在我了解订单项详细信息之前,一切对我来说都很好。我只得到数组中的第一项。我已经看到其他解决方案将其他数组项显示为附加列,但是我需要将它们视为行。我看到的很多例子也是用 C# 写的,我不太擅长。
订单Class
Imports ChoETL
Public Class Order
<ChoJSONRecordField>
Public Property Name As String
<ChoJSONRecordField>
Public Property Email As String
<ChoJSONRecordField(JSONPath:="financial_status")>
Public Property Financial_Status As String
<ChoJSONRecordField(JSONPath:="line_items[*].title")>
Public Property Title As String
End Class
创建 CSV 子文件
Private Shared Sub UsingPOCO()
Using csv = New ChoCSVWriter("order3.csv").WithFirstLineHeader()
Using json = New ChoJSONReader(Of Order)("order2.json")
csv.Write(json)
End Using
End Using
End Sub
样本JSON
{
"email": "anemail@adomain.com",
"financial_status": "paid",
"name": "#CCC94440",
"line_items": [
{
"title": "product1",
"quantity": 3
},
{
"title": "product2",
"quantity": 2
},
{
"title": "product3",
"quantity": 1
}
]
}
CSV 输出
我需要什么
或
更新 #1
我在另一个似乎在我想要的轨道上的问题上找到了这个答案。但是我不知道如何将它转换为 VB.net。我相信会起作用的答案是选定的答案更新 #2。
更新#2
我能够将 C# 从其他答案转换为 VB.net... 但是我收到以下错误,我仍在调查:“'Select' 不是 'Dynamic()' 的成员“
Using fw = New StreamWriter("order3.csv", True)
Using w = New ChoCSVWriter(fw).WithFirstLineHeader()
Using r = New ChoJSONReader("order2.json").WithJSONPath("$.line_items[*]")
w.Write(r.SelectMany(Function(r1) (CType(r1.line_items, Dynamic())).[Select](Function(r2) New With {r1.name, r2.title})))
End Using
End Using
End Using
Console.WriteLine(File.ReadAllText("order3.csv"))
更新 3
我不需要坚持使用 CHOETL,它只是我发现自己成功的第一件事。欢迎任何建议。
谢谢,
马特
这是 VB.NET
中的工作示例
Dim json As String
json = "
{
""email"": ""anemail@adomain.com"",
""financial_status"": ""paid"",
""name"": ""#CCC94440"",
""line_items"": [
{
""title"": ""product1"",
""quantity"": 3
},
{
""title"": ""product2"",
""quantity"": 2
},
{
""title"": ""product3"",
""quantity"": 1
}
]
}"
Dim csv As New StringBuilder
Using w = New ChoCSVWriter(csv).WithFirstLineHeader()
Using r = ChoJSONReader.LoadText(json)
w.Write(r.SelectMany(Function(r1) (CType(r1.line_items, Object())).[Select](Function(r2) New With {r1.email, r1.financial_status, r1.name, r2.title, r2.quantity})))
End Using
End Using
Console.WriteLine(csv.ToString())
输出:
email,financial_status,name,title,quantity
anemail@adomain.com,paid,#CCC94440,product1,3
anemail@adomain.com,paid,#CCC94440,product2,2
anemail@adomain.com,paid,#CCC94440,product3,1
更新#1:
从发货商品中检索价格
json = "
{
""email"": ""email@email.com"",
""financial_status"": ""paid"",
""name"": ""#CCC94440"",
""line_items"": [
{
""title"": ""item0"",
""quantity"": 3
},
{
""title"": ""item1"",
""quantity"": 2
}
],
""shipping_lines"": [
{
""title"": ""Free Shipping"",
""price"": ""1.00""
}
]
}
"
Dim csv As New StringBuilder
Using w = New ChoCSVWriter(csv).WithFirstLineHeader()
Using r = ChoJSONReader.LoadText(json)
w.Write(r.SelectMany(Function(r1) CType(r1.line_items, Object()).[Select](Function(r2)
Return New With
{
r1.email,
r1.financial_status,
r1.name,
r2.title,
r2.quantity,
CType(r1.shipping_lines, Object())(0).price
}
End Function)))
End Using
End Using
Console.WriteLine(csv.ToString())
输出:
email,financial_status,name,title,quantity,price
email@email.com,paid,#CCC94440,item0,3,1.00
email@email.com,paid,#CCC94440,item1,2,1.00
老实说,随着所有新出现的需求,继续尝试将所有这些都塞进一行 LINQ 中会变得越来越混乱...
我会前往 jsonutils.com 并将 json 粘贴到那里以将其转换为 VB,打开 PascalCase 和 JsonProperty 属性:
Public Class LineItem
<JsonProperty("title")>
Public Property Title As String
<JsonProperty("quantity")>
Public Property Quantity As Integer
End Class
Public Class ShippingLine
<JsonProperty("title")>
Public Property Title As String
<JsonProperty("price")>
Public Property Price As String
End Class
Public Class Example
<JsonProperty("email")>
Public Property Email As String
<JsonProperty("financial_status")>
Public Property FinancialStatus As String
<JsonProperty("name")>
Public Property Name As String
<JsonProperty("line_items")>
Public Property LineItems As LineItem()
<JsonProperty("shipping_lines")>
Public Property ShippingLines As ShippingLine()
End Class
然后一些循环更具可读性:
'inside Using w....
Dim root = NewtonSoft.Json.JsonConvert.DeserializeObject(your_json_string)
For Each li in root.LineItems
Dim csvLineObject = New With { _
root.email, _
root.financial_status, _
root.name, _
li.title, _
li.quantity, _
root.ShippingLines.First().Price, _
root.OtherArrayMightBeEmpty.FirstOrDefault()?.OtherProperty
}
w.Write(csvLineObject)
Next li
从未使用过 CHOETL,可能可以在 r 上使用类似的构造(= 此处为 root)
一直在努力解决以下问题:我收到来自我们电子商务网站 (Shopify) 的订单的 JSON 响应。我需要根据响应创建 CSV。在我了解订单项详细信息之前,一切对我来说都很好。我只得到数组中的第一项。我已经看到其他解决方案将其他数组项显示为附加列,但是我需要将它们视为行。我看到的很多例子也是用 C# 写的,我不太擅长。
订单Class
Imports ChoETL
Public Class Order
<ChoJSONRecordField>
Public Property Name As String
<ChoJSONRecordField>
Public Property Email As String
<ChoJSONRecordField(JSONPath:="financial_status")>
Public Property Financial_Status As String
<ChoJSONRecordField(JSONPath:="line_items[*].title")>
Public Property Title As String
End Class
创建 CSV 子文件
Private Shared Sub UsingPOCO()
Using csv = New ChoCSVWriter("order3.csv").WithFirstLineHeader()
Using json = New ChoJSONReader(Of Order)("order2.json")
csv.Write(json)
End Using
End Using
End Sub
样本JSON
{
"email": "anemail@adomain.com",
"financial_status": "paid",
"name": "#CCC94440",
"line_items": [
{
"title": "product1",
"quantity": 3
},
{
"title": "product2",
"quantity": 2
},
{
"title": "product3",
"quantity": 1
}
]
}
CSV 输出
我需要什么
或
更新 #1
我在另一个似乎在我想要的轨道上的问题上找到了这个答案。但是我不知道如何将它转换为 VB.net。我相信会起作用的答案是选定的答案更新 #2。
更新#2 我能够将 C# 从其他答案转换为 VB.net... 但是我收到以下错误,我仍在调查:“'Select' 不是 'Dynamic()' 的成员“
Using fw = New StreamWriter("order3.csv", True)
Using w = New ChoCSVWriter(fw).WithFirstLineHeader()
Using r = New ChoJSONReader("order2.json").WithJSONPath("$.line_items[*]")
w.Write(r.SelectMany(Function(r1) (CType(r1.line_items, Dynamic())).[Select](Function(r2) New With {r1.name, r2.title})))
End Using
End Using
End Using
Console.WriteLine(File.ReadAllText("order3.csv"))
更新 3
我不需要坚持使用 CHOETL,它只是我发现自己成功的第一件事。欢迎任何建议。
谢谢, 马特
这是 VB.NET
中的工作示例 Dim json As String
json = "
{
""email"": ""anemail@adomain.com"",
""financial_status"": ""paid"",
""name"": ""#CCC94440"",
""line_items"": [
{
""title"": ""product1"",
""quantity"": 3
},
{
""title"": ""product2"",
""quantity"": 2
},
{
""title"": ""product3"",
""quantity"": 1
}
]
}"
Dim csv As New StringBuilder
Using w = New ChoCSVWriter(csv).WithFirstLineHeader()
Using r = ChoJSONReader.LoadText(json)
w.Write(r.SelectMany(Function(r1) (CType(r1.line_items, Object())).[Select](Function(r2) New With {r1.email, r1.financial_status, r1.name, r2.title, r2.quantity})))
End Using
End Using
Console.WriteLine(csv.ToString())
输出:
email,financial_status,name,title,quantity
anemail@adomain.com,paid,#CCC94440,product1,3
anemail@adomain.com,paid,#CCC94440,product2,2
anemail@adomain.com,paid,#CCC94440,product3,1
更新#1:
从发货商品中检索价格
json = "
{
""email"": ""email@email.com"",
""financial_status"": ""paid"",
""name"": ""#CCC94440"",
""line_items"": [
{
""title"": ""item0"",
""quantity"": 3
},
{
""title"": ""item1"",
""quantity"": 2
}
],
""shipping_lines"": [
{
""title"": ""Free Shipping"",
""price"": ""1.00""
}
]
}
"
Dim csv As New StringBuilder
Using w = New ChoCSVWriter(csv).WithFirstLineHeader()
Using r = ChoJSONReader.LoadText(json)
w.Write(r.SelectMany(Function(r1) CType(r1.line_items, Object()).[Select](Function(r2)
Return New With
{
r1.email,
r1.financial_status,
r1.name,
r2.title,
r2.quantity,
CType(r1.shipping_lines, Object())(0).price
}
End Function)))
End Using
End Using
Console.WriteLine(csv.ToString())
输出:
email,financial_status,name,title,quantity,price
email@email.com,paid,#CCC94440,item0,3,1.00
email@email.com,paid,#CCC94440,item1,2,1.00
老实说,随着所有新出现的需求,继续尝试将所有这些都塞进一行 LINQ 中会变得越来越混乱...
我会前往 jsonutils.com 并将 json 粘贴到那里以将其转换为 VB,打开 PascalCase 和 JsonProperty 属性:
Public Class LineItem
<JsonProperty("title")>
Public Property Title As String
<JsonProperty("quantity")>
Public Property Quantity As Integer
End Class
Public Class ShippingLine
<JsonProperty("title")>
Public Property Title As String
<JsonProperty("price")>
Public Property Price As String
End Class
Public Class Example
<JsonProperty("email")>
Public Property Email As String
<JsonProperty("financial_status")>
Public Property FinancialStatus As String
<JsonProperty("name")>
Public Property Name As String
<JsonProperty("line_items")>
Public Property LineItems As LineItem()
<JsonProperty("shipping_lines")>
Public Property ShippingLines As ShippingLine()
End Class
然后一些循环更具可读性:
'inside Using w....
Dim root = NewtonSoft.Json.JsonConvert.DeserializeObject(your_json_string)
For Each li in root.LineItems
Dim csvLineObject = New With { _
root.email, _
root.financial_status, _
root.name, _
li.title, _
li.quantity, _
root.ShippingLines.First().Price, _
root.OtherArrayMightBeEmpty.FirstOrDefault()?.OtherProperty
}
w.Write(csvLineObject)
Next li
从未使用过 CHOETL,可能可以在 r 上使用类似的构造(= 此处为 root)