Робота з JSON в Power Fx
Power Fx дає розробникам змогу розшифрувати JSON у нетипізований об’єкт за допомогою функції ParseJSON.
Зчитування та перетворення значень
ParseJSON перетворить наступний рядок запису JSON в нетипізований об’єкт з полями ItemName
, Quantity
, ReleaseDate
і AvailableForPreOrder
.
{
"ItemName" : "Widget 1",
"Quantity" : 46,
"ReleaseDate" : "2022-09-01",
"AvailableForPreOrder" : true
}
Доступ до кожного з полів можна отримати за допомогою точкової нотації для значення Нетипізований об’єкт, який повернула функція ParseJSON.
Set( untyped, ParseJSON( jsonStringVariable ) );
Set( item, Text ( untyped.ItemName ) );
Set( quantity, Value ( untyped.Quantity ) );
Set( release, DateValue ( untyped.ReleaseDate ) );
Set( preorder, Boolean ( untyped.AvailableForPreOrder ) );
Як правило, це хороша ідея явно перетворити значення нетипізованого об’єкта в конкретний тип. Встановлення нетипізованого об’єкта як значення змінної робить змінну нетипізованим об’єктом. Отже, перетворення такого значення явно при встановленні в змінну, швидше за все, знадобиться. Але в більшості випадків значення нетипізованого об’єкта автоматично перетворюються на конкретний тип («примус»), коли використовуються як параметри функції, де тип є простим типом, таким як логічний, числовий або текстовий, а профіль параметрів функції не має потенційних конфліктних перевантажень.
Left( untyped.ItemName, 1 ); // "W"
Radians( untyped.Quantity ); // 0.80285146
If (untyped.AvailableForPreOrder, "Available", "Not Available" ); // "Available"
На додаток до автоматичної перетворення типу у викликах функцій, нетипізовані об’єкти також будуть перетворені при призначенні керуючим властивостям, де це можливо.
Label1.Text: untyped.Quantity
InputText1.Default: untyped.ItemName
І, нарешті, при використанні таких операторів , як &або +, нетипізований об’єкт буде примусовим, якщо немає двозначності щодо очікуваного типу.
untyped.Quantity + 1 // result is a number
untyped.ItemName & " (preorder)" // result is text
untyped.Quantity + untyped.Quantity // result is a number
untyped.Quantity & untyped.ItemName // result is text
Нотатка
JSON не має типу GUID, Color, Time або DateTime . Ці значення представляються у вигляді рядка. Якщо ви призначите значення JSONнетипізованого об’єкта значення, що містить дату, текстовій властивості безпосередньо, буде використовуватися оригінальний текст JSON . Це може бути важливо при роботі з часовими поясами, форматами дат тощо. У таких випадках вам слід явно перетворити значення за допомогою GUID(), ColorValue(), DateValue(), DateTimeValue() тощо.
Якщо ім’я поля складається з неприпустимого імені ідентифікатора (наприклад, імена полів починаються з цифри або містять неприпустимі символи, як-от дефіс), імена полів можна помістити в одинарні лапки.
untyped.'01'
untyped.'my-field'
Power Fx не оцінюватиме наявність поля, доки формулу не буде запущено. Це забезпечує гнучкість у вхідному форматі JSON. Наприклад, попередній формат JSON іноді може містити додаткове поле під назвою Discount
. Але в попередньому прикладі цього поля немає. Написання формули, у якій використовується поле Discount
, не призведе до виникнення помилок у процесі створення програми або під час використання програми користувачами. Якщо поле відсутнє під час виконання формули, значення буде Blank().
Нотатка
JSON підтримує null
значення для полів. Це також призведе до повернення значень Blank(). Наразі в Power Fx немає різниці між відсутнім полем і полем зі значенням null
.
Оскільки доступ до полів у нетипізованих об’єктах не оцінюється під час написання формули, то також відсутня система IntelliSense. Як JSON, так і Power Fx чутливі до регістру, тому будьте особливо уважні під час написання імен полів.
Значення JSON не обов’язково повинні бути в нотному стилі запису. Припустимий формат JSON може бути просто значенням, наприклад "text value"
, true
або 123.456
. У такому разі нетипізований об’єкт, який повертає функція ParseJSON, – це саме значення, а точкова нотація не використовується.
Set( myText, Boolean( ParseJSON( "true" ) ) );
Set( myNumber, Value( ParseJSON( "123.456" ) ) );
Зрештою, JSON підтримує вкладені записи. Перетворення таких JSON на нетипізований об’єкт призводить до вкладених об’єктів, і точкова нотація може використовуватися для обходу ієрархії.
{
"Version" : 1,
"RootElement" : {
"Parent" : {
"Name" : "This is the parent",
"Child" : {
"Name" : "This is the child"
}
}
}
}
Під час перетворення цього рядка JSON на змінну нетипізованого об’єкта під назвою jsonObject
доступ до полів можна отримати за допомогою точкової нотації.
Set( jsonObject, ParseJSON( jsonStringVariable ) );
Set( parentName, Text( jsonObject.RootElement.Parent.Name ) ); // "This is the parent"
Set( childName, Text( jsonObject.RootElement.Parent.Child.Name ) ); // "This is the child"
Якщо будь-які з полів у виразі точкової нотації не існують, повертається значення Blank().
Масиви й таблиці
JSON може містити масиви значень або записів. До цих масивів можна отримати доступ безпосередньо, або їх можна перетворити на таблиці Power Fx.
{
"OrderNumber" : "SO000010",
"CustomerID" : "CUST0126",
"OrderLines" : [
{
"Item" : "Widget 1",
"Quantity" : 3
},
{
"Item" : "Widget 2",
"Quantity" : 5
}
]
}
Цей JSON містить запис із полем OrderLines
, яке містить масив записів. Кожен запис має два поля: Item
і Quantity
. Якщо JSON перетворюється на нетипізований об’єкт за допомогою функції ParseJSON і для нього встановлюється змінна з іменем jsonOrder
, ми можемо отримати доступ до окремих рядків замовлення кількома способами.
Set( jsonOrder, ParseJSON( jsonStringVariable ) );
Ви можете отримати окремі записи та значення за допомогою функції Index(). Наприклад, щоб отримати другий запис у полі OrderLines
, перейдіть до поля Quantity
та перетворіть його на значення.
Set( line2Quantity, Value( Index( jsonOrder.OrderLines, 2 ).Quantity ); // 5
Масив рядків замовлення можна перетворити безпосередньо на таблицю. У результаті буде створено одностовпцеву таблицю з нетипізованим об’єктом, який представляє запис.
Set( orderLines, Table( jsonOrder.OrderLines ) );
Тепер в одностовпцевій таблиці orderLines є стовпець Value, який представляє нетипізований об’єкт. Щоб скористатися будь-яким із полів запису в цій таблиці, використовуйте точкову нотацію для доступу до конкретного поля JSON у нетипізованому об’єкті в стовпці Value
.
Set( jsonRecord, Index( orderLines, 2 ) ); // Get the second record in the table
Set( line2Item, Text( jsonRecord.Value.Item ) ); // "Widget 2"
Щоб спростити використання записів рядків замовлення в інших частинах програми, ви можете перетворити весь нетипізований об’єкт на повністю введений запис за допомогою функції ForAll(). Передавання нетипізованого об’єкта безпосередньо функції ForAll() означає, що ви можете отримати доступ до полів об’єкта напряму, а не шляхом використання поля Value
одностовпцевої таблиці.
Set( typedOrderLines, ForAll( jsonOrder.OrderLines, { Item : Text( ThisRecord.Item ), Quantity : Value( ThisRecord.Quantity ) } ) );
Нова змінна typedOrderLines
тепер є повністю введеною таблицею Power Fx з такими стовпцями та значеннями:
Елемент | Кількість |
---|---|
«Віджет 1» | 3 |
«Віджет 2» | 5 |
У попередніх прикладах використовуються масиви записів, але JSON також може містити масиви лише значень. Розгляньте наведений нижче приклад припустимого рядка JSON, що містить масив із трьох рядків.
[ "First Item", "Second Item", "Third Item"]
Ми можемо отримати один з елементів масиву за допомогою функції Index() і перетворити його на текст.
Text( Index( ParseJSON( jsonStringVariable ), 2 ) ) // "Second Item"