2013-03-13 125 views
3

在使用LINQ處理相當大的XML文檔時遇到了一些困難。基於子元素值選擇父XML元素LINQ C#

這裏是我的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 & & 經度< -121 & &> -123

的想法是捕獲METARs對於給定的區域。

這裏是我的代碼:

 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 
    ); 

我設法拿到了第一部分工作(排除具有空經緯度值的元素....但是我仍然可以說是邊界外METARs我想

任何建議

+1

l => l.Element(「latitude」)!= null || l.Element(「longitude」)!= null。更改||至 &&。 – arunlalam 2013-03-13 17:57:18

+0

這樣做。我很困惑,爲什麼......我認爲!= null排除了任何沒有Lat或Long的METAR ...因爲 - 我想要根據指定的條件篩選結果項目。 – JDBennett 2013-03-13 18:34:31

回答

1

由於@roughnex在評論,下面一行說:?

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

需要被改爲:

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

這樣做的原因是how boolean logic works

在你的代碼,您有以下條件語句:

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,那麼將忽略條件的其餘部分。這就是爲什麼你得到的結果超出了你想要的範圍,因爲它們的緯度不是零。

+0

這絕對有道理。我不宣稱要善於這樣(顯然)。但是 - 我從來沒有真正遇到過像我這樣的邏輯錯誤。我的印象是,所有的條件都必須得到滿足 - 不僅僅是第一個遇到真相的人。感謝您的澄清。 – JDBennett 2013-03-14 04:36:30

0

作爲參考,這是一個稱爲短路的編程概念。在布爾邏輯,如果有一個條件

A || B 

和A評估爲真,則B也不會被評估,因爲表達式(A || B)爲真而不管B的值的。類似地,如果

A && B 

和A的值爲false,那麼B不計算,因爲整個表達式會假,而不管B的值的。 (虛假& &真實將永遠是錯誤的。)

替代地,如果

A || B 

和A是假的,則B 必須進行評估,因爲在一個或比較,僅一個必須是真對整個表達式爲真(假| |真會是真的)。所以既然A是假的,B仍然有可能是真的,所以我們必須檢查。