プロパティ名が異なる場合のLINQとJSON.NET

arcgis-server c# json json.net

私はいくつかのJSONコンテンツをC#に解析しようとしています。 もっと単純なケースでは、私はJSON.NETで大成功を収めており、LINQプロバイダーによって提供されたクリーンなアプローチを本当に感謝しています。 これは私がマップ内のレイヤに関する情報をダウンロードし、(驚くべきことに!)Layerと呼ばれるクラスのいくつかのプロパティを埋める例です。

using(var client = new WebClient()){_content = client.DownloadString(_url.AbsoluteUri OutputFormats.Json); }

JObject json = JObject.Parse(_content); IEnumerable fields = from from json ["fields"]。Children()select new Field((文字列)f ["名前"]、(文字列)f ["エイリアス"]、(EsriFieldType)Enum.Parse(typeof(EsriFieldType) )、(文字列)f ["type"])); _fields = fields.ToList(); _displayFieldName =(文字列)json ["displayField"];

そのメソッドのJSONの詳細については、このURLを参照することができます。 しかし、個々のデータフィールドをマップレイヤに関連付けるデータテーブル、または単なる辞書構造に変換する必要があるときに問題が生じます。 問題は、RSSフィードや他の一貫したフォーマットとは異なり、フィールド名とフィールド数がマップレイヤごとに変わることです。 これは私がクエリを実行する例です。

[テスト] [カテゴリ(オンライン)] public void Can_query_a_single_feature_by_id(){var layer = _map.LayersWithName(ObjectMother.LayerWithoutOID)[0]; layer.FindFeatureById( "13141"); Assert.IsNotNull(layer.QueryResults); }

layer.FindFeatureByIdで実行されるコードはこれで、私が動けなくなる部分を含みます。

public void FindFeatureById(文字列ID){var queryThis = ObjectIdField() DisplayField(); var queryUrl = string.Format( "/ query {0} string.Format( "{0} = '{1}'"、queryThis.Name、id):string.Format( "{0} = {1}"、queryThis.Name、id); var where = queryUrl HttpUtility.UrlEncode(whereClause); var url = new Uri(_url.AbsoluteUri where); Debug.WriteLine(url.AbsoluteUri);文字列の結果。

using(var client = new WebClient()){result = client.DownloadString(url); }

JObject json = JObject.Parse(結果); IEnumerable fields = from from json ["fieldAliases"]。Children()select((JProperty)r).Name; IEnumerable fields = from json ["fieldAliases"]。 // Erm ...これを実現する方法がわかりません。 //基本的に、フィールドのリストが事前にわかっていない場合は、//各フィールドの//値をクラスインスタンス/行に設定する必要があります

}

このURLにアクセスするとJSONが吐き出されることがわかります(カットアンドペーストしたときのエンコードに注意してください)。 / query?f = json

だから私の質問は(ついに!)これです。 実際のフィールド値を取得するために、「機能」内の「属性」のコレクションをどのように循環させるのですか。 あなたは私がfieldAliasesからフィールド名を取得する方法を考え出したことがわかりますが、その後私は困惑します。 私はJsonReaderを使ってこのようなファイルを作成してきましたが、それでも喜びはありません。

{"displayFieldName": "FACILITYID"、 "fieldAliases":{"FACILITYID": "ファシリティ識別子"、 "アカウント識別子"、 "ロケーション識別子": "所在地識別子"、 "重要顧客"、 "ENABLED": "有効"、 "ACTIVEFLAG": "アクティブフラグ"、 "OWNEDBY": "所有者"、 "MAINTBY": "管理者"}、 "機能":[{"属性":{"FACILITYID" : "3689"、 "アカウント": "12425"、 "ロケーション": "12425"、 "クリティカル":1、 "有効":1、 "ACTIVEFLAG":1、 "OWNEDBY":1、 "MAINTBY":1 {}、{"属性":{"ファシリティID": "4222"、 "アカウント": "12958"、 "ロケーション": "12958"、 "重要":1、 "有効":1、 "ACTIVEFLAG":1 、 "OWNEDBY":1、 "MAINTBY":1}}]}

  9  3


ベストアンサー

属性と値を取得するための迅速で汚い(LINQ以外の)方法については、以下を試してください。

JObject jo = JObject.Parse(json);

foreach(JObject j in jo ["features"]){foreach(JProperty k in j ["attributes"]){Console.WriteLine(k.Name "=" k.Value); }}

理想的ではありませんが、戻ってくるフィールド名がわからないときに機能します。 これを実行するより良い方法が見つかった場合は、更新します。

6


最良の方法は、LINQを使用するのではなく、JsonTextReaderを使用してデータを取り込むことでした。 それは私を不幸にさせる刻み目でたくさん持っています、しかし私はそれが最初に階層的なデータ構造を使うことの直接の効果であると思います。 行のリスト(「属性」)とその名前/値のコレクションを印刷する方法は次のとおりです。

using(var file = File.OpenText(_fileWithGeom)){JsonReader reader = new JsonTextReader(file);

while(reader.Read()){while(Convert.ToString(reader.Value)!= "features"){reader.Read(); }

Console.WriteLine( "見つかった機能のコレクション");

//属性配列に到達するまでものを無視する

while(reader.Read()){switch(Convert.ToString(reader.Value)){case "attributes":Console.WriteLine( "Found feature"); reader.Read(); //パス属性プロパティを取得する

do {//まだ属性リストにある限り... if(reader.TokenType == JsonToken.PropertyName){var fieldName = Convert.ToString(reader.Value); reader.Read(); Console.WriteLine( "名前:{0}値:{1}"、fieldName、reader.Value); }

reader.Read();

(reader.TokenType!= JsonToken.EndObject)

case "geometry":Console.WriteLine( "Found geometry"); reader.Read();ブレーク; }}}}

今回はジオメトリも処理しなければならないので、JSON用のこのURLを調べて、上記のコードが解析されていることを確認してください。

3


タイトルとURLをコピーしました