2010-09-25 2 views
1

Je laisse le ci-dessous au cas où quelqu'un veut les types d'enregistrement, mais ma question peut être posée comme suit. Supposons que l'on doive écrire dans un fichier un type d'enregistrement pouvant être nul, quelle est la meilleure façon d'y parvenir, compte tenu des rendements ci-dessous: "Le type 'Basic' n'a pas de valeur nulle":Deserializing flux twitter json chaîne F #, comment définir «nul» comme une valeur correcte?

type Basic = {Toto:string} 

let basicToString b = function 
    |null -> "null" 
    |record->record.Toto 

Merci beaucoup


je le code suivant à désérialiser tweets de flux twitter:

open System.Runtime.Serialization 
open System.Runtime.Serialization.Json 
open System 
open System.Text 
open System.IO 


    let makeString numFields = 
    if numFields>1 then 
       seq[for i in 1..(numFields-1)->","] 
       |> Seq.fold(fun elem res-> elem+res) "" 
    else 
     "" 



[<DataContract>] 
type boundingbox = { 
    [<field: DataMember(Name = "type")>] 
    t:string 
    [<field: DataMember(Name = "coordinates")>] 
    coordinates:float array array array 
    } 
    with 
     member this.ToCsv() = let temp = string this 
           if temp ="" then 
            makeString 2 
           else 
            this.t+","+"coordinates" 




[<DataContract>] 
type attributes = { 
[<field: DataMember(Name = "street_adress")>] 
street_adress:string 
} 
    with 
     member this.ToCsv() = let temp = string this 
           if temp ="" then 
            makeString 1 
           else 
            this.street_adress 



[<DataContract>] 
type place = { 
    [<field: DataMember(Name = "country")>] 
    country:string 
    [<field: DataMember(Name = "url")>] 
    url:string 
    [<field: DataMember(Name = "attributes")>] 
    attributes:attributes 
    [<field: DataMember(Name = "country_code")>] 
    country_code:string 
    [<field: DataMember(Name = "full_name")>] 
    full_name:string 
    [<field: DataMember(Name = "name")>] 
    name:string 
    [<field: DataMember(Name = "id")>] 
    id:string 
    [<field: DataMember(Name = "bounding_box")>] 
    bounding_box:boundingbox 
    [<field: DataMember(Name = "pldace_type")>] 
    place_type:string 
    } 
    with 
     member this.toCsv() = let temp = string this 
           if temp ="" then 
            makeString 10 
           else 
            this.country+","+this.url+","+this.attributes.ToCsv()+","+this.country_code+","+this.full_name+","+this.name+","+this.bounding_box.ToCsv()+","+this.place_type 



[<DataContract>] 
type geo = { 
    [<field: DataMember(Name = "type")>] 
    t:string 
    [<field: DataMember(Name = "coordinates")>] 
    coordinates:float array 
    } 

[<DataContract>] 
type url = { 
    [<field: DataMember(Name = "url")>] 
    url:string 
    [<field: DataMember(Name = "indices")>] 
    indices:int array 
    } 

[<DataContract>] 
type hashtag = { 
    [<field: DataMember(Name = "text")>] 
    text:string 
    [<field: DataMember(Name = "indices")>] 
    indices:int array 
    } 


[<DataContract>] 
type user_mention = { 
    [<field: DataMember(Name = "indices")>] 
    indices:int array 
    [<field: DataMember(Name = "screen_name")>] 
    screen_name:string 
    [<field: DataMember(Name = "name")>] 
    name:string 
    [<field: DataMember(Name = "id")>] 
    id:string 
    } 

[<DataContract>] 
type entities = { 
    [<field: DataMember(Name = "urls")>] 
    urls:url array 
    [<field: DataMember(Name = "hashtags")>] 
    hashtags:hashtag array 
    [<field: DataMember(Name = "user_mentions")>] 
    user_mentions:user_mention array 
    } 

[<DataContract>] 
type user = { 
    [<field: DataMember(Name = "time_zone")>] 
    time_zone:string 
    [<field: DataMember(Name = "profile_sidebar_border_color")>] 
    profile_sidebar_border_color:string 
    [<field: DataMember(Name = "screen_name")>] 
    screen_name:string 
    [<field: DataMember(Name = "notifications")>] 
    notifications:string 
    [<field: DataMember(Name = "listed_count")>] 
    listed_count:string 
    [<field: DataMember(Name = "profile_background_image_url")>] 
    profile_background_image_url:string 
    [<field: DataMember(Name = "location")>] 
    location:string 
    [<field: DataMember(Name = "statuses_count")>] 
    statuses_count:string 
    [<field: DataMember(Name = "profile_background_color")>] 
    profile_background_color:string 
    [<field: DataMember(Name = "description")>] 
    description:string 
    [<field: DataMember(Name = "show_all_inline_media")>] 
    show_all_inline_media:string 
    [<field: DataMember(Name = "profile_background_tile")>] 
    profile_background_tile:string 
    [<field: DataMember(Name = "contributors_enabled")>] 
    contributors_enabled:string 
    [<field: DataMember(Name = "geo_enabled")>] 
    geo_enabled:string 
    [<field: DataMember(Name = "created_at")>] 
    created_at:string 
    [<field: DataMember(Name = "profile_text_color")>] 
    profile_text_color:string 
    [<field: DataMember(Name = "followers_count")>] 
    followers_count:string 
    [<field: DataMember(Name = "profile_use_background_image")>] 
    profile_use_background_image:string 
    [<field: DataMember(Name = "url")>] 
    url:string 
    [<field: DataMember(Name = "friends_count")>] 
    friends_count:string 
    [<field: DataMember(Name = "profile_link_color")>] 
    profile_link_color:string 
    [<field: DataMember(Name = "protected")>] 
    Protected:string 
    [<field: DataMember(Name = "lang")>] 
    lang:string 
    [<field: DataMember(Name = "verified")>] 
    verified:string 
    [<field: DataMember(Name = "name")>] 
    name:string 
    [<field: DataMember(Name = "follow_request_sent")>] 
    follow_request_sent:string 
    [<field: DataMember(Name = "following")>] 
    following:string 
    [<field: DataMember(Name = "favourites_count")>] 
    favourites_count:string 
    [<field: DataMember(Name = "profile_sidebar_fill_color")>] 
    profile_sidebar_fill_color:string 
    [<field: DataMember(Name = "profile_image_url")>] 
    profile_image_url:string 
    [<field: DataMember(Name = "id")>] 
    id:string 
    [<field: DataMember(Name = "utc_offset")>] 
    utc_offset:string 
} 




[<DataContract>] 
type tweet = { 
    [<field: DataMember(Name = "place")>] 
    place:place 
    [<field: DataMember(Name = "geo")>] 
    geo:geo 
    [<field: DataMember(Name = "text")>] 
    text:string 
    [<field: DataMember(Name = "coordinates")>] 
    coordinates:geo 
    [<field: DataMember(Name = "retweet_count")>] 
    retweet_count:string 
    [<field: DataMember(Name = "favorited")>] 
    favorited:string 
    [<field: DataMember(Name = "source")>] 
    source:string 
    [<field: DataMember(Name = "contributors")>] 
    contributors:int array 
    [<field: DataMember(Name = "created_at")>] 
    created_at:string 
    [<field: DataMember(Name = "in_reply_to_status_id")>] 
    in_reply_to_status_id:string 
    [<field: DataMember(Name = "in_reply_to_screen_name")>] 
    in_reply_to_screen_name:string 
    [<field: DataMember(Name = "user")>] 
    user:user 
    [<field: DataMember(Name = "retweeted")>] 
    retweeted:string 
    [<field: DataMember(Name = "in_reply_to_user_id")>] 
    in_reply_to_user_id:string 
    [<field: DataMember(Name = "truncated")>] 
    truncated:string 
    [<field: DataMember(Name = "id")>] 
    tweet_id:string 
    [<field: DataMember(Name = "entities")>] 
    entities:entities 
    } 



[<DataContract>] 
type fullTweet = { 
    [<field: DataMember(Name = "place")>] 
    place:place 
    [<field: DataMember(Name = "geo")>] 
    geo:geo 
    [<field: DataMember(Name = "text")>] 
    text:string 
    [<field: DataMember(Name = "coordinates")>] 
    coordinates:geo 
    [<field: DataMember(Name = "retweet_count")>] 
    retweet_count:string 
    [<field: DataMember(Name = "favorited")>] 
    favorited:string 
    [<field: DataMember(Name = "source")>] 
    source:string 
    [<field: DataMember(Name = "contributors")>] 
    contributors:int array 
    [<field: DataMember(Name = "created_at")>] 
    created_at:string 
    [<field: DataMember(Name = "in_reply_to_status_id")>] 
    in_reply_to_status_id:string 
    [<field: DataMember(Name="retweeted_status")>] 
    retweeted_status:tweet 
    [<field: DataMember(Name = "in_reply_to_screen_name")>] 
    in_reply_to_screen_name:string 
    [<field: DataMember(Name = "user")>] 
    user:user 
    [<field: DataMember(Name = "retweeted")>] 
    retweeted:string 
    [<field: DataMember(Name = "in_reply_to_user_id")>] 
    in_reply_to_user_id:string 
    [<field: DataMember(Name = "truncated")>] 
    truncated:string 
    [<field: DataMember(Name = "id")>] 
    tweet_id:string 
    [<field: DataMember(Name = "entities")>] 
    entities:entities 
    } 



let decodeFullTweet (s:string) = 
    let json = new DataContractJsonSerializer(typeof<fullTweet>) 
    let byteArray = Encoding.UTF8.GetBytes(s) 
    let stream = new MemoryStream(byteArray) 
    json.ReadObject(stream) :?>fullTweet 

let decodeUser (s:string) = 
    let json = new DataContractJsonSerializer(typeof<user>) 
    let byteArray = Encoding.UTF8.GetBytes(s) 
    let stream = new MemoryStream(byteArray) 
    json.ReadObject(stream) :?>user 

l'étape suivante où je dois se faire est de wr ite chaque enregistrement fullTweet à un fichier csv, le problème est que parfois certains des champs du type d'enregistrement sont null. Par exemple lors du décodage de la chaîne JSON (ci-dessous est juste une petite partie de la chaîne):

rel = \\ "nofollow \\"> TweetDeck \ ", \" favorisé \ ": false, \" in_reply_to_status_id \ ": null, \" entités \ ": {\" hashtags \ ": [{\" text \ ": \" frac1 \ ", \" indices \ ": [117,123]}], \" user_mentions \ ": [ ], \ "urls \": []}, \ "place \": null, \ "coordonnées \": null, \ "geo \": null, \ "in_reply_to_user_id \": null, \ "

Les champs "place" et "in_reply_to_user_id" seront null.

Comment puis-je gérer cela de telle sorte que lorsqu'un champ est nul (par exemple des lieux), la ligne csv indique "null" (pour chaque champ de l'endroit du type d'enregistrement)? Ou si vous avez une meilleure façon de gérer cela?

Merci beaucoup!

(Hope certains vont profiter de tous les types d'enregistrement :))

+0

Avez-vous déjà du code ou une idée pour générer le fichier CSV? Sinon, la question est difficile à répondre. La gestion des valeurs NULL dépend de la création du fichier CSV. – wmeyer

+0

@wmeyer Merci de votre visite. Ma question n'est pas très claire, désolé. J'ai édité mon post avec une solution qui "fonctionne" mais elle semble un peu moche. – jlezard

+0

N'avez pas de réponse à votre question, mais trouvez votre utilisation du pliage dans la fonction makeString très ingénieuse. Cependant, si vous voulez laisser cela à la bibliothèque F #, vous pouvez utiliser 'let makeString numFields = String.init numFields (fun _ -> ",")' à la place. –

Répondre

0

Si je comprends ce que vous demandez, vous avez juste besoin d'une fonction qui prend une chaîne et retourne la chaîne si elle est non nulle et retour " null "si c'est null:

let fieldToString = function 
    | null -> "null" 
    | field -> field 
+0

Swenson Merci pour votre aide, pour imprimer le champ d'un enregistrement cela fonctionnera (si l'enregistrement global n'est pas nul). Le vrai problème est si vous essayez de le faire sur le dossier complet. J'ai édité ma question originale. – jlezard

+0

Vous pouvez considérer '[]' http://msdn.microsoft.com/en-us/library/ee353608.aspx – Brian

+0

@Brian Merci. Savez-vous s'il y a moyen d'utiliser un type d'option lors de la désérialisation? Dans le type fullTweet, chaque champ peut exister ou non (None/Some), puis chaque sous-champ peut exister ou non (None/Some), etc .. donc un type d'option semble très naturel – jlezard