Delen via


Werken met JSON in Power Fx

Met Power Fx kunnen makers JSON in een niet-getypeerd object lezen met de functie ParseJSON.

Waarden lezen en converteren

ParseJSON converteert de volgende JSON recordreeks naar een niet-getypeerd object met velden ItemName, Quantity, ReleaseDate en AvailableForPreOrder.

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

Elk van de velden is toegankelijk met behulp van de puntnotatie voor de geretourneerde waarde voor niet-getypeerde objecten van 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 ) );

Het is over het algemeen een goed idee om de waarde van een niet-getypeerd object expliciet te converteren naar een specifiek type. Als u een niet-getypeerd object instelt als een variabele waarde, wordt de variabele ook een niet-getypeerd object. Het is dus waarschijnlijk nodig om een dergelijke waarde expliciet te converteren bij het instellen in een variabele. Maar in de meeste gevallen worden waarden van niet-getypeerde objecten automatisch naar een specifiek type worden geconverteerd (gedowngen) wanneer ze worden gebruikt als functieparameters waarbij het type een eenvoudig type is, zoals booleaans, getal of tekst, en er voor het parameterprofiel van de functie geen potentiële conflicterende overbelastingen bestaan.

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

Naast het automatisch converteren van het type in functieaanroepen, worden niet-getypeerde objecten waar mogelijk ook geconverteerd wanneer ze worden toegewezen aan besturingseigenschappen.

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

En tot slot: als operators zoals & of + worden gebruikt, wordt een niet-getypeerd object afgedwongen als er geen onduidelijkheid bestaat over het verwachte type.

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

Notitie

JSON heeft geen GUID, Color, Time of DateTime type. Deze waarden worden weergegeven als een tekenreeks. Als u een waarde voor een niet-getypeerd object voor JSON met een datum rechtstreeks aan een teksteigenschap toewijst, wordt de oorspronkelijke tekst van de JSON gebruikt. Dit kan belangrijk zijn bij het omgaan met tijdzones, datumnotaties, enzovoort. In dergelijke gevallen moet u de waarden expliciet converteren met GUID(), ColorValue(), DateValue(), DateTimeValue(), enzovoort.

Als een veldnaam uit een ongeldige identificatienaam bestaat, bijvoorbeeld wanneer de veldnamen beginnen met een cijfer of ongeldige tekens bevatten, zoals een koppelteken, kunt u de veldnamen tussen enkele aanhalingstekens plaatsen:

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

Power Fx evalueert het bestaan van het veld pas als de formule wordt uitgevoerd. Dit zorgt voor flexibiliteit in de inkomende JSON. De vorige JSON kan bijvoorbeeld soms een extra veld genaamd Discount bevatten. Maar in ons vorige voorbeeld is dit veld niet aanwezig. Een formule schrijven die gebruikmaakt van het veld Discount levert geen fouten op tijdens het proces van het maken van de app of wanneer gebruikers de app gebruiken. Als het veld ontbreekt wanneer de formule wordt uitgevoerd, resulteert de waarde alleen in de waarde Blank().

Notitie

JSON ondersteunt null waarden voor velden. Deze resulteren ook in de waarde Blank(). Momenteel is er geen onderscheid in Power Fx tussen een ontbrekend veld of een veld met de waarde null.

Als toegang tot velden voor niet-getypeerde objecten niet wordt geëvalueerd bij het schrijven van de formule, er is ook geen IntelliSense beschikbaar. Zowel JSON als Power Fx is hoofdlettergevoelig, dus wees extra voorzichtig bij het uitschrijven van veldnamen.

JSON waarden hoeven niet in een record-stijl notatie te zijn. Een geldige JSON kan gewoon een waarde zijn, zoals "text value", true of 123.456. In een dergelijk geval is het niet-getypeerde object dat ParseJSON retourneert de waarde zelf en de puntnotatie wordt niet gebruikt.

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

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

JSON ondersteunt ook geneste records. Het converteren van een dergelijke JSON naar een niet-getypeerd object resulteert in geneste objecten en de puntnotatie kan worden gebruikt om de hiërarchie te doorlopen.

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

Bij het converteren van deze JSON-tekenreeks naar een variabele voor een niet-getypeerd object genaamd jsonObject, zijn de velden toegankelijk met behulp van de puntnotatie.

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"

Als een van de velden in de puntnotatie-expressie niet bestaat, wordt Blank() geretourneerd.

Matrices en tabellen

JSON kan arrays met waarden of records bevatten. Deze matrices zijn direct toegankelijk of kunnen worden geconverteerd naar Power Fx-tabellen.

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

Deze JSON bevat een record met een veld met de naam OrderLines, dat een matrix met records bevat. Elk record heeft twee velden: Item en Quantity. Als de JSON wordt geconverteerd naar een niet-getypeerd object met de functie ParseJSON en ingesteld op een variabele met de naam jsonOrder, hebben we op verschillende manieren toegang tot de afzonderlijke orderregels.

Set( jsonOrder, ParseJSON( jsonStringVariable ) );

U kunt afzonderlijke records en waarden ophalen met behulp van de functie Index(). U kunt bijvoorbeeld de tweede record in het veld OrderLines ophalen en vervolgens het veld Quantity openen en deze converteren naar een waarde.

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

U kunt de matrix met orderregels direct naar een tabel converteren. Er wordt een tabel met één kolom gemaakt met een niet-getypeerd object dat voor de record staat.

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

De tabel met één kolom orderLines bevat nu een waardekolom voor niet-getypeerde objecten. als u een van de velden uit een record in deze tabel wilt gebruiken, gebruikt u de puntnotatie om toegang te krijgen tot het specifieke JSON-veld voor het niet-getypeerde object in de kolom Value.

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

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

Om het gebruik van de orderregelrecords in andere delen van uw app eenvoudiger te maken, kunt u het hele niet-getypeerde object naar een volledig getypeerde record converteren met de functie ForAll(). Als het niet-getypeerde object rechtstreeks aan ForAll() wordt verstrekt, hebt u rechtstreeks toegang tot de objectvelden in plaats van het veld met één kolom Value te gebruiken.

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

De nieuwe variabele typedOrderLines is nu een volledige getypeerde Power Fx-tabel met de volgende kolommen en waarden:

Artikel Aantal
"Widget 1" 5
"Widget 2" 5

De vorige voorbeelden gebruiken recordmatrices, maar JSON kan ook matrices met alleen waarden bevatten. Bekijk het volgende voorbeeld dat een geldige JSON-tekenreeks is met een matrix van drie tekenreeksen.

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

We kunnen een van de items uit de matrix ophalen met behulp van de functie Index() en deze converteren naar tekst.

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