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


Работа с 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 не приведет к каким-либо ошибкам в процессе создания приложения или при использовании приложения пользователями. Если поле отсутствует при выполнении формулы, значение просто будет Пустым().

Заметка

JSON поддерживает null значения для полей. Это также приведет к Пустым() значениям. В настоящее время нет различий в 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"

Если какое-либо из полей в выражении точечной нотации не существует, возвращается значение Пусто().

Таблицы и массивы

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 ) );

Вы можете получить отдельные записи и значения, используя функцию Указатель(). Например, чтобы получить вторую запись в поле OrderLines, перейдите к полю Quantity и преобразуйте его в значение.

Set( line2Quantity, Value( Index( jsonOrder.OrderLines, 2 ).Quantity ); // 5

Вы можете преобразовать массив строк заказа непосредственно в таблицу. Это создаст таблицу с одним столбцом с Нетипизированным объектом, представляющим запись.

Set( orderLines, Table( jsonOrder.OrderLines ) );

Таблица с одним столбцом "orderLines" теперь имеет столбец "Значение", который представляет Нетипизированный объект. Чтобы использовать любое из полей записи в этой таблице, используйте точечную нотацию для доступа к конкретному полю 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"]

Мы можем получить один из элементов массива с помощью функции Указатель() и преобразовать ее в текст.

Text( Index( ParseJSON( jsonStringVariable ), 2 ) ) // "Second Item"