Power Fx 允许制造商使用 ParseJSON 函数将 JSON 读入动态值。
读取和转换值
ParseJSON 将以下 JSON 记录字符串转换为包含字段的ItemName记录,QuantityReleaseDate以及AvailableForPreOrder。
{
"ItemName" : "Widget 1",
"Quantity" : 46,
"ReleaseDate" : "2022-09-01",
"AvailableForPreOrder" : true
}
可以使用 ParseJSON 返回的动态值上的点表示法访问每个字段。
Set( dynvalue, ParseJSON( jsonStringVariable ) );
Set( item, Text ( dynamic.ItemName ) );
Set( quantity, Value ( dynamic.Quantity ) );
Set( release, DateValue ( dynamic.ReleaseDate ) );
Set( preorder, Boolean ( dynamic.AvailableForPreOrder ) );
通常最好将动态值显式转换为特定类型。 将动态设置为变量值也会使变量成为动态值。 因此,可能需要在设置为变量时明确转换此类值。 但在大多数情况下,当用作函数参数时,动态值将自动转换为特定类型(“强制”),其中类型是一种简单类型,如布尔值、数字或文本,并且函数的参数配置文件没有潜在的冲突重载。
Left( dynamic.ItemName, 1 ); // "W"
Radians( dynamic.Quantity ); // 0.80285146
If (dynamic.AvailableForPreOrder, "Available", "Not Available" ); // "Available"
除了在函数调用中自动转换类型外,在可能的情况下,还将在分配给控件属性时转换动态值。
Label1.Text: dynamic.Quantity
InputText1.Default: dynamic.ItemName
最后, 如果使用运算符 (如 & 或 +)时,如果预期类型没有歧义,则动态值将强制执行。
dynamic.Quantity + 1 // result is a number
dynamic.ItemName & " (preorder)" // result is text
dynamic.Quantity + dynamic.Quantity // result is a number
dynamic.Quantity & dynamic.ItemName // result is text
备注
JSON 没有 GUID、Color、 Time 或 DateTime 类型。 这些值表示为字符串。 如果将包含日期的 JSON 动态值直接分配给文本属性,将使用 JSON 的原始文本。 在处理时区、日期格式等时,这可能非常重要。在这种情况下,您应该使用 GUID()、ColorValue()、DateValue()、DateTimeValue() 等显式转换值。
如果字段名包含无效的标识符名称,例如,当字段名以数字开头或包含无效字符(如连字符)时,可以将字段名放在单引号内:
dynamic.'01'
dynamic.'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。 如果使用 ParseJSON 函数将 JSON 转换为动态值并设置为名为jsonOrder变量,则可以通过多种方式访问单个订单行。
Set( jsonOrder, ParseJSON( jsonStringVariable ) );
您可以使用 Index() 函数检索各个记录和值。 例如,要获取 OrderLines 字段中的第二个记录,然后访问 Quantity 字段并将其转换为值。
Set( line2Quantity, Value( Index( jsonOrder.OrderLines, 2 ).Quantity ) ); // 5
您可以将订单行数组直接转换为表。 这将创建一个单列表,其中包含表示记录的 动态 值。
Set( orderLines, Table( jsonOrder.OrderLines ) );
单列表“orderLines”现在有一个表示 动态 值的“值”列。 若要使用此表中记录中的任何字段,请使用点表示法访问列中动态值上的特定 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 表,具有以下列和值:
| Item | 数量 |
|---|---|
| “小组件 1” | 3 |
| “小组件 2” | 5 |
前面的示例使用记录数组,但 JSON 也可以包含只有值的数组。 考虑以下示例,它是一个有效的 JSON 字符串,其中包含三个字符串的数组。
[ "First Item", "Second Item", "Third Item"]
我们可以使用 Index() 函数从数组中检索项目中的一项,然后将其转换为文本。
Text( Index( ParseJSON( jsonStringVariable ), 2 ) ) // "Second Item"