Поділитися через


Робота з 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

І, нарешті, при використанні таких операторів , як &or+, нетипізований об’єкт буде примусовим, якщо в очікуваному типі немає амбіджіуті.

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"