LINQ中的If语句(如果没有值,做点什么…)
本文关键字:什么 If 中的 语句 如果没有 LINQ | 更新日期: 2023-09-27 18:06:03
我正在尝试制作一个应用程序,显示巴士时间,包括巴士号码,目标时间和预期时间。
我从HttpWebRequest
获得我的(实时)信息。请求的响应以XML格式存储在字符串变量中。
我可以得到我想要的所有信息;比如公交车时间、预定时间和预期时间。
问题是,如果没有预期时间,将不会显示任何内容。我喜欢在没有预期小时的情况下,我的代码只采用与目标小时相同的值:
一个例子Bus | Aimed | Execepted
-----------------------
1 | 17:05 | 17:07
2 | 17:05 | <nothing> so take value of aimed -> 17:05
我已经有了以下代码
//XMLResponse put in documentRoot
//responseFromServer is a string variable in XML format with all the information
XElement documentRoot = XDocument.Parse(responseFromServer).Root;
XNamespace ns = "http://www.siri.org.uk/";
var buses = (from tblBuses in documentRoot.Descendants(ns + "PublishedLineName")
select tblBuses.Value).ToList();
var expHours = (from tblHours in documentRoot.Descendants(ns + "ExpectedDepartureTime")
select tblHours.Value).ToList();
foreach (var bus in buses)
{
string output = bus.Substring(bus.IndexOf('T') + 1);
int index = output.IndexOf(".");
if (index > 0)
output = output.Substring(0, index);
listBox1.Items.Add("Bus: " + output);
}
//Show every ExpectedDepartureTime
//If there is no expectedTime take value AimedDepartureTime
foreach (var expH in expHours)
{
string output = expH.Substring(expH.IndexOf('T') + 1);
int index = output.IndexOf(".");
if (index > 0)
output = output.Substring(0, index);
lstHours.Items.Add(output);
}
为了更清楚地理解我的XML响应,下面是我的XML响应的示例(一个带有AimedDeparturetime和Expected,另一个没有Expected)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Siri version="1.0" xmlns="http://www.siri.org.uk/">
<ServiceDelivery>
<ResponseTimestamp>2013-03-26T16:09:48.181Z</ResponseTimestamp>
<StopMonitoringDelivery version="1.0">
<ResponseTimestamp>2013-03-26T16:09:48.181Z</ResponseTimestamp>
<RequestMessageRef>12345</RequestMessageRef>
<MonitoredStopVisit>
<RecordedAtTime>2013-03-26T16:09:48.181Z</RecordedAtTime>
<MonitoringRef>020035811</MonitoringRef>
<MonitoredVehicleJourney>
<FramedVehicleJourneyRef>
<DataFrameRef>-</DataFrameRef>
<DatedVehicleJourneyRef>-</DatedVehicleJourneyRef>
</FramedVehicleJourneyRef>
<VehicleMode>bus</VehicleMode>
<PublishedLineName>2</PublishedLineName>
<DirectionName>Elstow P+R</DirectionName>
<OperatorRef>STB</OperatorRef>
<MonitoredCall>
<AimedDepartureTime>2013-03-26T16:11:00.000Z</AimedDepartureTime>
<ExpectedDepartureTime>2013-03-26T16:11:28.000Z</ExpectedDepartureTime>
</MonitoredCall>
</MonitoredVehicleJourney>
</MonitoredStopVisit>
---------------------------------------------------
<MonitoredStopVisit>
<RecordedAtTime>2013-03-26T16:09:48.181Z</RecordedAtTime>
<MonitoringRef>020035811</MonitoringRef>
<MonitoredVehicleJourney>
<FramedVehicleJourneyRef>
<DataFrameRef>-</DataFrameRef>
<DatedVehicleJourneyRef>-</DatedVehicleJourneyRef>
</FramedVehicleJourneyRef>
<VehicleMode>bus</VehicleMode>
<PublishedLineName>53</PublishedLineName>
<DirectionName>Wootton</DirectionName>
<OperatorRef>STB</OperatorRef>
<MonitoredCall>
<AimedDepartureTime>2013-03-26T16:19:00.000Z</AimedDepartureTime>
</MonitoredCall>
</MonitoredVehicleJourney>
</MonitoredStopVisit>
</StopMonitoringDelivery>
</ServiceDelivery>
</Siri>
因此,目前我的应用程序没有显示巴士的每次出发时间。
我该如何解决这个问题?
谢谢!
首先道歉,因为这不是最好的XML解析,但是我会调整我的LINQ查询:
var buses = from tblBuses in documentRoot.Descendants(ns + "MonitoredVehicleJourney")
select new
{
LineName = tblBuses.Descendants(ns + "PublishedLineName").Single().Value,
AimedHours = tblBuses.Descendants(ns + "AimedDepartureTime").Single().Value,
ExpectedHours = tblBuses.Descendants(ns + "ExpectedDepartureTime").Select(el => el.Value).SingleOrDefault()
};
这将创建一个匿名类型的IEnumerable
,使您可以在随后的代码中更容易地访问总线数据:
foreach (var bus in buses)
{
// Take ExpectedHours, or AimedHours if the first is null
string expH = bus.ExpectedHours ?? bus.AimedHours
// Same code as before here
string output = expH.Substring(expH.IndexOf('T') + 1);
int index = output.IndexOf(".");
if (index > 0)
output = output.Substring(0, index);
lstHours.Items.Add(output);
}
在您的原始代码中,没有<ExpectedDepartureTime>
的总线从未迭代过,因为它们从未出现在您的expHours
列表中。相反,这个LINQ查询将包含所有总线。它假设它们都有一个<AimedDepartureTime>
和一个可选的<ExpectedDepartureTime>
。
对于预期的出发时间,我使用Select
来获取每个后代的元素值。不能使用SingleOrDefault().Value
,因为查询可能不会产生任何元素,并且get_Value()
将在null
引用上被调用。
关于我的查询的最后一个评论:对于生产代码,我将避免使用Descendants
,并对XML结构进行更严格的查询。
您可以在一个linq查询中完成所有操作,并使用?:
条件运算符来选择正确的输出:
var buses =
(from tblBuses in documentRoot.Descendants(ns + "PublishedLineName")
let bus = tblBuses.Value
let output = bus.Substring(bus.IndexOf('T') + 1)
let index = output.IndexOf(".")
select (index > 0) ? output.Substring(0, index) : output);
foreach (var bus in buses)
{
listBox1.Items.Add("Bus: " + bus);
}
或者
var buses =
(from ...
select "Bus: " + ((index > 0) ? output.Substring(0, index) : output));
.ToArray();
listBox1.Items.AddRange(buses);
同样的模式可以应用于expHours