문제

C#에 JSON 컨텐츠를 구문 분석하려고합니다. 간단한 경우에 나는 JSON.NET에서 큰 성공을 거두고 있으며 LINQ 제공 업체가 제공하는 깨끗한 접근 방식에 정말 감사합니다. 다음은지도에서 레이어에 대한 정보를 다운로드하고 (놀라운!) 레이어라는 클래스에서 일부 속성을 채우는 예입니다.

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

        JObject json = JObject.Parse(_content);
        IEnumerable<Field> fields = from f in json["fields"].Children()
                                    select new Field(
                                        (string)f["name"],
                                        (string)f["alias"],
                                        (EsriFieldType)Enum.Parse(typeof(EsriFieldType), (string)f["type"])
                                        );
        _fields = fields.ToList();
        _displayFieldName = (string)json["displayField"];

이 방법에 대한 JSON의 자세한 내용은이 URL을 볼 수 있습니다. http://sampleserver1.arcgisonline.com/arcgis/rest/services/watertemplate/waterdotributionnetwork/mapserver/1?f=json&pretty=true. 그러나 개별 데이터 필드를 맵 레이어와 연결해야 할 때 문제는 데이터 가능 또는 사전 구조로 바꿔야 할 때 발생합니다. 문제는 RSS 피드 또는 기타 일관된 형식과 달리 필드 이름과 필드 수가 맵 레이어에서 맵 레이어로 변경된다는 것입니다. 다음은 쿼리를 실행하는 예입니다.

    [Test]
    [Category(Online)]
    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(string id)
    {
        var queryThis = ObjectIdField() ?? DisplayField();
        var queryUrl = string.Format("/query{0}&outFields=*&where=", OutputFormats.Json);
        var whereClause = queryThis.DataType == typeof(string)
                                 ? 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);
        string result;

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

        JObject json = JObject.Parse(result);
        IEnumerable<string> fields = from r in json["fieldAliases"].Children()
                                     select ((JProperty)r).Name;
        // Erm...not sure how to get this done.
        // Basically need to populate class instances/rows with the 
        // values for each field where the list of fields is not
        // known beforehand.

    }

이 URL을 방문하여 JSON이 침을 뱉는 것을 볼 수 있습니다 (컷을 끊을 때 인코딩 참고) : href = "http://sampleserver1.arcgisonline.com/arcgis/rest/services/watertemplate/waterdistributionnetwork/mapserver/1 /query? f = JSON & Outfields =*& where = facilityId%3d'13141 '

그래서 내 질문 (마침내!)은 이것입니다. 실제 필드 값을 얻기 위해 "기능"에서 "속성"모음을 순환하는 방법 당신은 내가 현장에서 필드 이름을 얻는 방법을 알아 냈다는 것을 알 수 있지만 그 후에 나는 그무입니다. 나는 이렇게 보이는 파일에서 JSONREADER와 함께 땜질을했지만 여전히 기쁨은 없습니다.

{
  "displayFieldName" : "FACILITYID", 
  "fieldAliases" : {
  "FACILITYID" : "Facility Identifier", 
  "ACCOUNTID" : "Account Identifier", 
  "LOCATIONID" : "Location Identifier", 
  "CRITICAL" : "Critical Customer", 
  "ENABLED" : "Enabled", 
  "ACTIVEFLAG" : "Active Flag", 
  "OWNEDBY" : "Owned By", 
  "MAINTBY" : "Managed By"
}, 
"features" : [
  {
    "attributes" : {
      "FACILITYID" : "3689", 
      "ACCOUNTID" : "12425", 
      "LOCATIONID" : "12425", 
      "CRITICAL" : 1, 
      "ENABLED" : 1, 
      "ACTIVEFLAG" : 1, 
      "OWNEDBY" : 1, 
      "MAINTBY" : 1
    }
  }, 
  {
    "attributes" : {
      "FACILITYID" : "4222", 
      "ACCOUNTID" : "12958", 
      "LOCATIONID" : "12958", 
      "CRITICAL" : 1, 
      "ENABLED" : 1, 
      "ACTIVEFLAG" : 1, 
      "OWNEDBY" : 1, 
      "MAINTBY" : 1
    }
  }
]
}
도움이 되었습니까?

해결책 2

가장 좋은 방법은 JSONTEXTREADER를 사용하고 LINQ를 사용하지 않고 데이터를 찢는 것입니다. 그것은 들여 쓰기에 많은 것을 가지고있어서 나를 불행하게 만듭니다. 그러나 나는 그것이 처음에 계층 적 데이터 구조를 사용하는 직접적인 효과라고 생각합니다. 행 목록 ( "속성") 및 이름/값 수집을 인쇄하는 방법은 다음과 같습니다.

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

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

                Console.WriteLine("Found feature collections");

                // ignore stuff until we get to attribute array

                while (reader.Read())
                {
                    switch (Convert.ToString(reader.Value))
                    {
                        case "attributes":
                            Console.WriteLine("Found feature");
                            reader.Read(); // get pass attributes property

                            do
                            {
                                // As long as we're still in the attribute list...
                                if (reader.TokenType == JsonToken.PropertyName)
                                {
                                    var fieldName = Convert.ToString(reader.Value);
                                    reader.Read();
                                    Console.WriteLine("Name: {0}  Value: {1}", fieldName, reader.Value);
                                }

                                reader.Read();

                            } while (reader.TokenType != JsonToken.EndObject
                                     && Convert.ToString(reader.Value) != "attributes");
                            break;

                        case "geometry":
                            Console.WriteLine("Found geometry");
                            reader.Read();
                            break;
                    }
                }
            }
        }

그리고 이번에는 지오메트리를 처리해야하므로 위의 코드가 구문 분석하는 JSON 의이 URL을 확인하십시오.

http://sampleserver1.arcgisonline.com/arcgis/rest/services/watertemplate/waterdotributionnetwork/mapserver/7/query?where=ObjectId%3C10&returngeoometrety=true&outsr=&outfields=*& f = pjson

다른 팁

속성과 값을 얻을 수있는 빠르고 더러운 (LINQ가 아닌) 방법은 다음을 시도하십시오.

JObject jo = JObject.Parse(json);

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

이상적이지는 않지만 돌아올 필드 이름을 모를 때 작동합니다. 더 나은 방법을 찾으면 업데이트하겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top