3

LINQを使用してかなり大きなXMLドキュメントをフィルタリングするのが難しい。

これが私のXML(その一部)です...

  <?xml version="1.0" encoding="UTF-8"?>
<response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XML-Schema-instance" version="1.2" xsi:noNamespaceSchemaLocation="http://weather.aero/schema/metar1_2.xsd">
  <request_index>54966812</request_index>
  <data_source name="metars" />
  <request type="retrieve" />
  <errors />
  <warnings />
  <time_taken_ms>3</time_taken_ms>
  <data num_results="6">
    <METAR>
      <raw_text>KDEN 131653Z 06007KT 9SM FEW080 SCT140 BKN250 09/01 A3025 RMK AO2 SLP238 T00940006</raw_text>
      <station_id>KDEN</station_id>
      <observation_time>2013-03-13T16:53:00Z</observation_time>
      <latitude>39.83</latitude>
      <longitude>-104.65</longitude>
      <temp_c>9.4</temp_c>
      <dewpoint_c>0.6</dewpoint_c>
      <wind_dir_degrees>60</wind_dir_degrees>
      <wind_speed_kt>7</wind_speed_kt>
      <visibility_statute_mi>9.0</visibility_statute_mi>
      <altim_in_hg>30.250984</altim_in_hg>
      <sea_level_pressure_mb>1023.8</sea_level_pressure_mb>
      <quality_control_flags>
        <auto_station>TRUE</auto_station>
      </quality_control_flags>
      <sky_condition sky_cover="FEW" cloud_base_ft_agl="8000" />
      <sky_condition sky_cover="SCT" cloud_base_ft_agl="14000" />
      <sky_condition sky_cover="BKN" cloud_base_ft_agl="25000" />
      <flight_category>VFR</flight_category>
      <metar_type>METAR</metar_type>
      <elevation_m>1640.0</elevation_m>
    </METAR>
    <METAR>
      <raw_text>KSEA 131653Z 20006KT 10SM FEW008 BKN070 OVC200 11/08 A3019 RMK AO2 SLP232 T01060083</raw_text>
      <station_id>KSEA</station_id>
      <observation_time>2013-03-13T16:53:00Z</observation_time>
      <latitude>47.45</latitude>
      <longitude>-122.32</longitude>
      <temp_c>10.6</temp_c>
      <dewpoint_c>8.3</dewpoint_c>
      <wind_dir_degrees>200</wind_dir_degrees>
      <wind_speed_kt>6</wind_speed_kt>
      <visibility_statute_mi>10.0</visibility_statute_mi>
      <altim_in_hg>30.188976</altim_in_hg>
      <sea_level_pressure_mb>1023.2</sea_level_pressure_mb>
      <quality_control_flags>
        <auto_station>TRUE</auto_station>
      </quality_control_flags>
      <sky_condition sky_cover="FEW" cloud_base_ft_agl="800" />
      <sky_condition sky_cover="BKN" cloud_base_ft_agl="7000" />
      <sky_condition sky_cover="OVC" cloud_base_ft_agl="20000" />
      <flight_category>VFR</flight_category>
      <metar_type>METAR</metar_type>
      <elevation_m>136.0</elevation_m>
    </METAR>

私がやろうとしているのは、緯度と経度の範囲内にあるすべてのMETAR要素を取得することです。例えば:

緯度>52&&<55経度<-121&&>-123

アイデアは、特定のエリアのMETARをキャプチャすることです。

これが私のコードです:

     double southLat = 52.09;
     double northLat = 53.95;
     double westLong = -123.17;
     double eastLong = -121.87;

     XDocument response = XDocument.Load("file");

     var metars = response.Descendants("METAR")
        .Where
        (l => l.Element("latitude") != null || l.Element("longitude") != null
        && (Double)l.Element("latitude") >= southLat 
        && (Double)l.Element("latitude") <= northLat
        && (Double)l.Element("longitude") >= westLong
        && (Double)l.Element("longitude") <= eastLong
   );

私はなんとか最初の部分を機能させることができました(緯度または経度の値がnullの要素を除外します....ただし、希望する範囲外のMETARを取得します。

助言がありますか?

4

2 に答える 2

1

@roughnexがコメントで言ったように、次の行:

l.Element("latitude") != null || l.Element("longitude") != null

次のように変更する必要があります:

l.Element("latitude") != null && l.Element("longitude") != null

この理由は、ブール論理がどのように機能するかです。

コードには、次の条件文があります。

l.Element("latitude") != null || l.Element("longitude") != null
&& (Double)l.Element("latitude") >= southLat 
&& (Double)l.Element("latitude") <= northLat
&& (Double)l.Element("longitude") >= westLong
&& (Double)l.Element("longitude") <= eastLong

しかし、詳細を切り取って、各文字が条件である場合は簡単にしましょう。

A || B && C && D && F

A単純な用語に減らすと、に解決された場合True、残りの条件が無視されることがわかりやすくなります。そのため、緯度がnullではなかったため、目的の領域外の結果が得られていました。

于 2013-03-13T19:28:48.267 に答える
0

参考までに、これは短絡と呼ばれるプログラミングの概念です。ブール論理では、条件がある場合

A || B

Aがtrueと評価された場合、式(A || B)はBの値に関係なくtrueになるため、Bは評価されません。同様に、

A && B

Aがfalseと評価された場合、Bの値に関係なく、式全体がfalseと評価されるため、Bは評価されません。(False && trueは常にfalseになります。)

または、

A || B 

Aがfalseの場合、Bを評価する必要があります。これは、OR比較では、式全体がtrueになるには1つだけがtrueである必要があるためです(False || TrueはTrueになります)。したがって、Aが偽であるため、Bが真である可能性がまだあるので、確認する必要があります。

于 2013-08-01T23:26:24.873 に答える