根据子元素值选择父XML元素
本文关键字:元素 XML 选择 | 更新日期: 2023-09-27 18:03:57
在使用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 &&& lt;55经度& lt;-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。
有什么建议吗?
正如@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
,则忽略条件的其余部分。这就是为什么你得到的结果在你想要的区域之外,因为它们的纬度不是空的。
作为参考,这是一个叫做短路的编程概念。在布尔逻辑中,如果你有一个条件
A || B
且A求值为真,则B不会被求值,因为表达式(A || B)无论B的值如何都将为真。类似地,如果
A && B
且A求值为false,则不求B,因为无论B的值是什么,整个表达式都会求值为false。(错误,,True总是false)
或者,if
A || B
和A为假,则B 必须求值,因为在OR比较中,只有一个为真才能使整个表达式为真(false || true将为真)。既然A为假,B仍有可能为真,所以我们需要检查