Compartir a través de


Trabajar con JSON en Power Fx

Power Fx permite a los fabricantes leer el JSON de un Objeto sin tipo utilizando la función ParseJSON.

Lectura y conversión de valores

ParseJSON convertirá la siguiente cadena de registro JSON en un Objeto sin tipo con los campos ItemName, Quantity, ReleaseDate y AvailableForPreOrder.

{
  "ItemName" : "Widget 1",
  "Quantity" : 46,
  "ReleaseDate" : "2022-09-01",
  "AvailableForPreOrder" : true
}

Se puede acceder a cada uno de los campos usando la notación de puntos en el valor Objeto sin tipo devuelto desde 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 ) );

Por lo general, es una buena idea convertir explícitamente el valor de un objeto sin tipo a un tipo específico. Establecer un objeto sin tipo como un valor de variable convierte a la variable en un objeto sin tipo también. Por tanto, es probable que sea necesario convertir dicho valor explícitamente cuando se configura una variable. Pero en la mayoría de los casos, los valores de objeto sin tipo se convertirán a un tipo específico automáticamente ("forzar") cuando se usen como parámetros de función donde el tipo es un tipo simple como booleano, número o texto, y el perfil de parámetro de la función no tiene posibles sobrecargas conflictivas.

Left( untyped.ItemName, 1 ); // "W"
Radians( untyped.Quantity ); // 0.80285146
If (untyped.AvailableForPreOrder, "Available", "Not Available" ); // "Available"

Además de convertir automáticamente el tipo en llamadas a funciones, los objetos sin tipo también se convertirán cuando se asignen a propiedades de control, siempre que sea posible.

Label1.Text: untyped.Quantity
InputText1.Default: untyped.ItemName

Y finalmente, cuando utiliza operadores como & o +, un objeto sin tipo será forzado si no hay ambigüedad en el tipo esperado.

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

Nota

JSON no tiene un tipo GUID, Color, Tiempo o Fecha y hora. Estos valores se representan como una cadena. Si asigna un valor de objeto sin tipo JSON que contiene una fecha a una propiedad de texto directamente, se utilizará el texto original del JSON. Esto puede ser importante cuando se trata de zonas horarias, formatos de fecha, etc. En tales casos, debe convertir explícitamente los valores usando GUID(), ColorValue(), DateValue(), DateTimeValue(), etc.

En caso de que un nombre de campo consista en un nombre de identificador no válido, por ejemplo cuando los nombres de campo comienzan con un número o contienen caracteres no válidos como un guion, puede poner los nombres de campo entre comillas simples:

untyped.'01'
untyped.'my-field'

Power Fx no evaluará la existencia del campo hasta que se ejecute la fórmula. Esto permite flexibilidad en la entrada JSON. Por ejemplo, el anterior JSON a veces puede contener un campo extra llamado Discount. Pero en nuestro ejemplo anterior, este campo no está presente. Escribir una fórmula que use el campo Discount no generará ningún error, durante el proceso de creación de la aplicación o cuando los usuarios usen la aplicación. Si falta el campo cuando se ejecuta la fórmula, el valor solo dará como resultado un valor Blank().

Nota

JSON admite valores null para los campos. Estos también darán como resultado valores Blank(). Actualmente, no hay distinción en Power Fx entre un campo que falta o un campo que tiene el valor null.

Como acceder a campos en Objetos sin tipo no se evalúa al escribir la fórmula, tampoco está disponible Intellisense. Ambas cosas, JSON y Power Fx distinguen entre mayúsculas y minúsculas, así que tenga mucho cuidado al escribir los nombres de los campos.

Los valores JSON no tienen que estar en una notación de estilo de registro. El JSON válido puede ser solo un valor, como "text value", true o 123.456. En tal caso, el Objeto sin tipo que devuelve ParseJSON es el valor en sí mismo y no se utiliza la notación de puntos.

Set( myText, Boolean( ParseJSON( "true" ) ) );

Set( myNumber, Value( ParseJSON( "123.456" ) ) );

Finalmente, JSON admite registros anidados. Convertir tal JSON en Objeto sin tipo da como resultado objetos anidados, y la notación de puntos se puede utilizar para recorrer la jerarquía.

{
  "Version" : 1,
  "RootElement" : {
    "Parent" : {
      "Name" : "This is the parent",
      "Child" : {
        "Name" : "This is the child"
      }
    }
  }
}

Al convertir esta cadena JSON en una variable de Objeto sin tipo denominada jsonObject, se puede acceder a los campos usando la notación de puntos.

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"

Si alguno de los campos en la expresión de notación de puntos no existe, se devuelve Blank().

Matrices y tablas

JSON puede contener matrices de valores o registros. Se puede acceder a estas matrices directamente o convertirlas en tablas Power Fx.

{
  "OrderNumber" : "SO000010",
  "CustomerID" : "CUST0126",
  "OrderLines" : [
    {
      "Item" : "Widget 1",
      "Quantity" : 3
    },
    {
      "Item" : "Widget 2",
      "Quantity" : 5
    }
  ]
}

Este JSON contiene un registro con un campo llamado OrderLines, que contiene una matriz de registros. Cada registro tiene dos campos: Item y Quantity. Si el JSON se convierte en un Objeto sin tipo utilizando la función ParseJSON y se establece en una variable llamada jsonOrder, podemos acceder a las líneas de orden individuales de varias formas.

Set( jsonOrder, ParseJSON( jsonStringVariable ) );

Puede recuperar registros y valores individuales mediante la función Index(). Por ejemplo, para obtener el segundo registro del campo OrderLines, se debe acceder al campo Quantity y convertirlo en un valor.

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

Puede convertir la matriz de líneas de pedido directamente a una tabla. Esto creará una tabla de una sola columna con un Objeto sin tipo que representa el registro.

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

La tabla de una sola columna 'orderLines' ahora tiene una columna 'Valor' que representa el Objeto sin tipo. Para usar cualquiera de los campos de un registro en esta tabla, use la notación de puntos para acceder al campo específico JSON del Objeto sin tipo en la columna Value.

Set( jsonRecord, Index( orderLines, 2 ) ); // Get the second record in the table

Set( line2Item, Text( jsonRecord.Value.Item ) ); // "Widget 2"

Para que el uso de los registros de línea de pedido sea más fácil y sencillo en otras partes de su aplicación, puede convertir todo el Objeto sin tipo en un registro completamente con tipos usando la función ForAll(). Si se proporciona el objeto sin tipo directamente para ForAll(), significa que puede acceder a los campos de objeto directamente en lugar de usar el campo Value de columna única.

Set( typedOrderLines, ForAll( jsonOrder.OrderLines, { Item : Text( ThisRecord.Item ), Quantity : Value( ThisRecord.Quantity ) } ) );

La nueva variable typedOrderLines ahora es una tabla de Power Fx completamente con tipos, con las siguientes columnas y valores:

Item Cantidad
"Widget 1" 3
"Widget 2" 5

Los ejemplos anteriores usan matrices de registros, pero JSON también puede contener matrices de solo valores. Considere el siguiente ejemplo que es una cadena JSON válida que contiene una matriz de tres cadenas.

[ "First Item", "Second Item", "Third Item"]

Podemos recuperar uno de los elementos de la matriz usando la función Index() y convertirlo en texto.

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