一直在努力解决以下问题:我有来自我们的电子商务网站 (Shopify) 的订单的 JSON 响应。 我需要根据响应创建 CSV。 在我了解订单项详细信息之前,一切对我来说都很好。 我只得到数组中的第一项。 我已经看到其他解决方案将其他数组项显示为附加列,但我需要将它们视为行。 我见过的很多例子也是用 C# 编写的,我不太擅长。
订购类
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": "[email protected]",
"financial_status": "paid",
"name": "#CCC94440",
"line_items": [
{
"title": "product1",
"quantity": 3
},
{
"title": "product2",
"quantity": 2
},
{
"title": "product3",
"quantity": 1
}
]
}
CSV 输出
我需要什么
或
更新#1 我在另一个问题上找到了这个答案,这个问题似乎在我想要的轨道上。 但是我不知道如何将其转换为 VB.net。 我相信有效的答案是选定的答案更新#2。 https://stackoverflow.com/a/57166153/2037475
更新#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"": ""[email protected]"",
""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
[email protected],paid,#CCC94440,product1,3
[email protected],paid,#CCC94440,product2,2
[email protected],paid,#CCC94440,product3,1
更新#1:
从运输项目中检索价格
json = "
{
""email"": ""[email protected]"",
""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 protected],paid,#CCC94440,item0,3,1.00
[email protected],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 上使用类似的构造(=此处为根)