Haskell :: Aeson :: analysiert ADT basierend auf Feldwerten

8

Ich verwende eine externe API, die JSON-Antworten zurückgibt. Eine der Antworten ist ein Array von Objekten, und diese Objekte werden durch den Feldwert in ihnen identifiziert. Ich habe Probleme zu verstehen, wie das Parsen einer solchen JSON-Antwort mit Aeson durchgeführt werden kann.

Hier ist eine vereinfachte Version meines Problems:

%Vor%

In der API-Dokumentation heißt es, dass das Objekt durch das Feld objectClass mit dem Wert "video" für unser Video -Objekt und "audiobook" für unser AudioBook und so weiter. Beispiel JSON:

%Vor%

Die Frage ist, wie kann diese Art von JSON mit Aeson angegangen werden?

%Vor%     
ksaveljev 26.08.2014, 08:03
quelle

2 Antworten

7

Sie benötigen grundsätzlich eine Funktion Text -> Text -> Media :

%Vor%

Die FromJSON Instanz ist jetzt wirklich einfach (mit <$> und <*> von Control.Applicative ):

%Vor%

An diesem Punkt sind Sie jedoch redundant: Das objectClass -Feld in Video oder Audio gibt Ihnen nicht mehr Informationen als der tatsächliche Typ, sodass Sie es möglicherweise entfernen können:

%Vor%

Beachten Sie auch, dass toMedia teilweise ist. Wahrscheinlich möchten Sie ungültige "objectClass" -Werte abfangen:

%Vor%

Und zuletzt, nicht zuletzt, denken Sie daran, dass gültiger JSON Strings für den Namen verwendet.

    
Zeta 26.08.2014, 08:28
quelle
2

Die Standardübersetzung für einen Datentyp wie:

%Vor%

ist eigentlich sehr nah an dem, was Sie wollen. (Zur Vereinfachung meiner Beispiele definiere ich ToJSON Instanzen und codiere die Beispiele, um zu sehen, welche Art von JSON wir erhalten.)

aeson, Standard

Also, mit der Standardinstanz, die wir haben (view die vollständige Quelldatei , die diese Ausgabe erzeugt:

%Vor%

Mal sehen, ob wir mit benutzerdefinierten Optionen noch näher kommen können ...

aeson, benutzerdefiniert tagFieldName

Mit benutzerdefinierten Optionen :

%Vor%

wir bekommen:

%Vor%

(Denken Sie selbst darüber nach, was Sie mit einem undefinierten Feld im echten Code machen möchten.)

aeson, benutzerdefiniert constructorTagModifier

Hinzufügen

%Vor%

bis mediaJSONOptions gibt:

%Vor%

Großartig! Genau das, was Sie angegeben haben!

Decodierung

Fügen Sie einfach eine Instanz mit den gleichen Optionen hinzu, um aus diesem Format zu dekodieren:

%Vor%

Beispiel:

%Vor%

Komplette Quelldatei .

generic-aeson, Standard

Um ein vollständigeres Bild zu erhalten, schauen wir uns auch an, was generic-aeson Paket ( hackage ). Es hat auch einige Standard-Übersetzungen, die sich in einigen Punkten von denen von aeson unterscheiden.

Machen

%Vor%

und definieren:

%Vor%

gibt das Ergebnis:

%Vor%

Es unterscheidet sich also von allem, was wir bei der Verwendung von aeson gesehen haben.

generic-aesons Optionen ( Einstellungen ) sind für uns nicht interessant (sie erlauben nur das Entfernen eines Präfixes).

( Das Ganze Quelldatei .)

aeson, ObjectWithSingleField

Abgesehen von lower-casing, dem ersten Buchstaben der Konstruktornamen, scheint die Übersetzung von generic-aeson einer Option ähnlich zu sein, die in aeson verfügbar ist:

Versuchen wir das:

%Vor%

und ja, das Ergebnis ist:

%Vor%

die restlichen Optionen: (aeson, TwoElemArray )

Eine verfügbare Option für sumEncoding wurde aus der obigen Betrachtung herausgelassen, weil es ein Array ergibt, das der geforderten JSON-Darstellung nicht sehr ähnlich ist. Es ist TwoElemArray . Beispiel:

%Vor%

ist gegeben durch:

%Vor%     
quelle

Tags und Links