如何将 json 转换为 FoxPro 游标
How to convert json to FoxPro cursor
文件包含 json 格式的发票列表,例如:
{
"status": "OK", "statusCode": 200, "messages": null,
"data": [{
"payment_type": "banktransfer", "fine": "0.200000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [],
"interested_party_address_id": 279, "project_id": 875, "currency": "EUR", "owner_id": 3, "date": "2019-03-15", "deadline": "2019-03-20",
},
{
"payment_type": "banktransfer", "fine": "0.30000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [],
"interested_party_address_id": 79, "project_id": 85, "currency": "EUR", "owner_id": 3, "date": "2019-04-15", "deadline": "2019-43-20",
}
.... more same type elements
]
}
如何将其转换为 FoxPRo 游标?
光标应包含 payment_type、fine、quote_id 等列。
我试过了
https://archive.codeplex.com/?p=qdfoxjson
和
http://www.sweetpotatosoftware.com/blog/index.php/2008/12/19/visual-foxpro-json-class-update/
但看起来他们要求 json 的格式与我的 json 格式不同。
安德鲁斯
只是我为你想出的一个简单的东西。如果我有更多类似格式的东西,我会做一些 "looking for begin delimiter"、"looking for end delimiter"、"final data type" 等的 cursor/table 结构……然后循环遍历每个部分。在这里,我实际上展示了如何提取每个部分以及如何一次获取一个数据行。
** Example to put into a string called "json", no other context to json
TEXT TO json noshow
{
"status": "OK", "statusCode": 200, "messages": null,
"data": [{1
"payment_type": "banktransfer", "fine": "0.200000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [],
"interested_party_address_id": 279, "project_id": 875, "currency": "EUR", "owner_id": 3, "date": "2019-03-15", "deadline": "2019-03-20",
},
{2
"payment_type": "banktransfer", "fine": "0.30000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [],
"interested_party_address_id": 79, "project_id": 85, "currency": "EUR", "owner_id": 3, "date": "2019-04-15", "deadline": "2019-43-20",
}
.... more same type elements
]
}
ENDTEXT
** Strip the "Status" component ang get just the Data
json = SUBSTR( json, ATC( ["data":], json ))
CREATE CURSOR C_ImportRecs;
( PayType c(20),;
Fine n(10,6),;
QuoteID i,;
OrderID i,;
PrepayID i,;
Invoices c(20),;
IntPartyAddrID i,;
ProjectID i,;
TransCurrency c(3),;
OwnerID i,;
DatePart c(15),;
TransDate d,;
DeadPart c(15),;
Deadline d )
** scatter all fields to an object which will have fields by same name
SCATTER NAME newRec
** start counter to 1
nRow = 1
DO while .t.
** Look within the json string for the "nRow" instance of data starting / ending with { / }
oneData = STREXTRACT( json, "{", "}", nRow )
** if no more entries, get out
IF EMPTY( ALLTRIM( oneData ))
exit
ENDIF
** if memory variables are same name as cursor/table columns, simplifies insert
newRec.PayType = STREXTRACT( oneData, ["payment_type": "], ["] )
newRec.Fine = VAL( STREXTRACT( oneData, ["fine": "], ["] ))
** not including closing quote as ending delimiter since null allowed, looking for the "," after the IDs
newRec.QuoteID = INT( VAL( STREXTRACT( oneData, ["quote_id": ], [,] ) ))
newRec.OrderID = INT( VAL( STREXTRACT( oneData, ["order_id": ], [,] ) ))
newRec.PrepayID = INT( VAL( STREXTRACT( oneData, ["prepayment_id": ], [,] ) ))
newRec.Invoices = STREXTRACT( oneData, ["credited_invoices": ], [,] )
newRec.IntPartyAddrID = INT( VAL( STREXTRACT( oneData, ["interested_party_address_id": ], [,] ) ))
newRec.ProjectID = INT( VAL( STREXTRACT( oneData, ["project_id": ], [,] ) ))
** Currency is reserved word.
newRec.TransCurrency = STREXTRACT( oneData, ["currency": "], ["] )
newRec.OwnerID = INT( VAL( STREXTRACT( oneData, ["owner_id": ], [,] ) ))
** Date is reserved word
newRec.DatePart = ""
newRec.DatePart = STREXTRACT( oneData, ["date": "], ["] )
** Nice for macro substitution. Take incoming date format of ex: "2019-03-15"
** and change to "2019,03,15" This is because the DATE() function expects
** 3 parameters for YEAR, MONTH, DAY
tryDate = STRTRAN( newRec.DatePart, "-", "," )
** Now, by using macro via "&" forces the line below to immediately run as if
** run as if it was DATE( 2019,03,15) and create an actual date value
TRY
newRec.TransDate = DATE( &tryDate )
CATCH
newRec.TransDate = CTOD( "" )
ENDTRY
** same for deadline
newRec.DeadPart = STREXTRACT( oneData, ["deadline": "], ["] )
tryDate = STRTRAN( newRec.DeadPart, "-", "," )
TRY
** your second record has a month 43 which is an invalid month
newRec.Deadline = DATE( &tryDate )
CATCH
newRec.Deadline = CTOD( "" )
ENDTRY
** Since the cursor "C_ImportRecs" is already the active focus,
** we can just insert from memory variables
INSERT INTO C_ImportRecs FROM NAME newRec
** try if any more records
nRow = nRow + 1
ENDDO
BROWSE NORMAL NOCAPTIONS NOWAIT
首先是您的 JSON 无效。 "deadline" 日期值后不应该有逗号。
第二件事是没有机制告诉 VFP 如何将元素映射到字段。所以你必须自己做。
为此,我将使用 njJson 库,特别是 nfJsonRead
。
假设您的 JSON 在文件 'test.json' 中并且您有 nfJsonRead.prg 那么例如:
Close All
Clear All
Clear
Set Procedure To nfJsonRead additive
* -- Add the other fields as appropriate.
Create Cursor mydata (payment_type c(20), fine n(12, 2))
loJson = nfjsonread(FileToStr("test.json"))
For each loData in loJson.data
Insert into mydata values (loData.payment_type, Val(loData.fine))
EndFor
文件包含 json 格式的发票列表,例如:
{ "status": "OK", "statusCode": 200, "messages": null, "data": [{ "payment_type": "banktransfer", "fine": "0.200000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [], "interested_party_address_id": 279, "project_id": 875, "currency": "EUR", "owner_id": 3, "date": "2019-03-15", "deadline": "2019-03-20", }, { "payment_type": "banktransfer", "fine": "0.30000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [], "interested_party_address_id": 79, "project_id": 85, "currency": "EUR", "owner_id": 3, "date": "2019-04-15", "deadline": "2019-43-20", } .... more same type elements ] }
如何将其转换为 FoxPRo 游标? 光标应包含 payment_type、fine、quote_id 等列。
我试过了
https://archive.codeplex.com/?p=qdfoxjson
和
http://www.sweetpotatosoftware.com/blog/index.php/2008/12/19/visual-foxpro-json-class-update/
但看起来他们要求 json 的格式与我的 json 格式不同。
安德鲁斯
只是我为你想出的一个简单的东西。如果我有更多类似格式的东西,我会做一些 "looking for begin delimiter"、"looking for end delimiter"、"final data type" 等的 cursor/table 结构……然后循环遍历每个部分。在这里,我实际上展示了如何提取每个部分以及如何一次获取一个数据行。
** Example to put into a string called "json", no other context to json
TEXT TO json noshow
{
"status": "OK", "statusCode": 200, "messages": null,
"data": [{1
"payment_type": "banktransfer", "fine": "0.200000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [],
"interested_party_address_id": 279, "project_id": 875, "currency": "EUR", "owner_id": 3, "date": "2019-03-15", "deadline": "2019-03-20",
},
{2
"payment_type": "banktransfer", "fine": "0.30000", "quote_id": null, "order_id": null, "prepayment_id": null, "credited_invoices": [],
"interested_party_address_id": 79, "project_id": 85, "currency": "EUR", "owner_id": 3, "date": "2019-04-15", "deadline": "2019-43-20",
}
.... more same type elements
]
}
ENDTEXT
** Strip the "Status" component ang get just the Data
json = SUBSTR( json, ATC( ["data":], json ))
CREATE CURSOR C_ImportRecs;
( PayType c(20),;
Fine n(10,6),;
QuoteID i,;
OrderID i,;
PrepayID i,;
Invoices c(20),;
IntPartyAddrID i,;
ProjectID i,;
TransCurrency c(3),;
OwnerID i,;
DatePart c(15),;
TransDate d,;
DeadPart c(15),;
Deadline d )
** scatter all fields to an object which will have fields by same name
SCATTER NAME newRec
** start counter to 1
nRow = 1
DO while .t.
** Look within the json string for the "nRow" instance of data starting / ending with { / }
oneData = STREXTRACT( json, "{", "}", nRow )
** if no more entries, get out
IF EMPTY( ALLTRIM( oneData ))
exit
ENDIF
** if memory variables are same name as cursor/table columns, simplifies insert
newRec.PayType = STREXTRACT( oneData, ["payment_type": "], ["] )
newRec.Fine = VAL( STREXTRACT( oneData, ["fine": "], ["] ))
** not including closing quote as ending delimiter since null allowed, looking for the "," after the IDs
newRec.QuoteID = INT( VAL( STREXTRACT( oneData, ["quote_id": ], [,] ) ))
newRec.OrderID = INT( VAL( STREXTRACT( oneData, ["order_id": ], [,] ) ))
newRec.PrepayID = INT( VAL( STREXTRACT( oneData, ["prepayment_id": ], [,] ) ))
newRec.Invoices = STREXTRACT( oneData, ["credited_invoices": ], [,] )
newRec.IntPartyAddrID = INT( VAL( STREXTRACT( oneData, ["interested_party_address_id": ], [,] ) ))
newRec.ProjectID = INT( VAL( STREXTRACT( oneData, ["project_id": ], [,] ) ))
** Currency is reserved word.
newRec.TransCurrency = STREXTRACT( oneData, ["currency": "], ["] )
newRec.OwnerID = INT( VAL( STREXTRACT( oneData, ["owner_id": ], [,] ) ))
** Date is reserved word
newRec.DatePart = ""
newRec.DatePart = STREXTRACT( oneData, ["date": "], ["] )
** Nice for macro substitution. Take incoming date format of ex: "2019-03-15"
** and change to "2019,03,15" This is because the DATE() function expects
** 3 parameters for YEAR, MONTH, DAY
tryDate = STRTRAN( newRec.DatePart, "-", "," )
** Now, by using macro via "&" forces the line below to immediately run as if
** run as if it was DATE( 2019,03,15) and create an actual date value
TRY
newRec.TransDate = DATE( &tryDate )
CATCH
newRec.TransDate = CTOD( "" )
ENDTRY
** same for deadline
newRec.DeadPart = STREXTRACT( oneData, ["deadline": "], ["] )
tryDate = STRTRAN( newRec.DeadPart, "-", "," )
TRY
** your second record has a month 43 which is an invalid month
newRec.Deadline = DATE( &tryDate )
CATCH
newRec.Deadline = CTOD( "" )
ENDTRY
** Since the cursor "C_ImportRecs" is already the active focus,
** we can just insert from memory variables
INSERT INTO C_ImportRecs FROM NAME newRec
** try if any more records
nRow = nRow + 1
ENDDO
BROWSE NORMAL NOCAPTIONS NOWAIT
首先是您的 JSON 无效。 "deadline" 日期值后不应该有逗号。
第二件事是没有机制告诉 VFP 如何将元素映射到字段。所以你必须自己做。
为此,我将使用 njJson 库,特别是 nfJsonRead
。
假设您的 JSON 在文件 'test.json' 中并且您有 nfJsonRead.prg 那么例如:
Close All
Clear All
Clear
Set Procedure To nfJsonRead additive
* -- Add the other fields as appropriate.
Create Cursor mydata (payment_type c(20), fine n(12, 2))
loJson = nfjsonread(FileToStr("test.json"))
For each loData in loJson.data
Insert into mydata values (loData.payment_type, Val(loData.fine))
EndFor