我正在努力解决从yahoo finance通过yql返回的股票市场数据的LINQ to XML查询问题。有些字段带有错误的数据或空值。我目前的错误是:
输入字符串的格式不正确。
我为我感兴趣的每个元素添加了一个检查空值,但错误仍然存在。
如果有帮助,看似抛出异常的突出显示的代码部分是包含我的数据点对象的“新”初始化的块。如果XML传递了查询中的检查,则在初始化DailyPricingVolDP
时将空值传递给构造函数时会抛出错误。
Func<string, DateTime?> tryToGetDate =
value =>
{
DateTime dateValue;
return DateTime.TryParse(value, out dateValue)
? (DateTime?)dateValue
: null;
};
XDocument doc = XDocument.Load(addressString);
XElement results = doc.Root.Element("results");
CultureInfo enUS = new CultureInfo("en-US");
DateTime targetDate = new DateTime(2012, 1, 25);
var makeInfo =
from s in doc.Descendants("quote")
where s.Element("LastTradeDate") != null
&& s.Attribute("symbol") != null
let dateStr = s.Element("LastTradeDate").Value
let dateValue = tryToGetDate(dateStr)
where dateValue != null && (DateTime)dateValue == targetDate
&& s.Element("Open") != null && s.Element("DaysHigh") != null
&& s.Element("DaysLow") != null && s.Element("LastTradePriceOnly") != null
&& s.Element("Volume") != null
select new DailyPricingVolDP(
(string)s.Attribute("symbol"),
(DateTime)s.Element("LastTradeDate"),
(double)s.Element("Open"),
(double)s.Element("DaysHigh"),
(double)s.Element("DaysLow"),
(double)s.Element("LastTradePriceOnly"),
(long)s.Element("Volume"));
<quote symbol="AFFM">
<Ask>0.89</Ask>
<AverageDailyVolume>6523</AverageDailyVolume>
<Bid>0.67</Bid>
<AskRealtime>0.89</AskRealtime>
<BidRealtime>0.67</BidRealtime>
<BookValue>4.804</BookValue>
<Change_PercentChange>0.00 - 0.00%</Change_PercentChange>
<Change>0.00</Change>
<Commission />
<ChangeRealtime>0.00</ChangeRealtime>
<AfterHoursChangeRealtime>N/A - N/A</AfterHoursChangeRealtime>
<DividendShare>0.00</DividendShare>
<LastTradeDate>1/25/2012</LastTradeDate>
<TradeDate />
<EarningsShare>-4.491</EarningsShare>
<ErrorIndicationreturnedforsymbolchangedinvalid />
<EPSEstimateCurrentYear>0.00</EPSEstimateCurrentYear>
<EPSEstimateNextYear>0.00</EPSEstimateNextYear>
<EPSEstimateNextQuarter>0.00</EPSEstimateNextQuarter>
<DaysLow />
<DaysHigh />
<YearLow>0.42</YearLow>
<YearHigh>2.95</YearHigh>
<HoldingsGainPercent>- - -</HoldingsGainPercent>
<AnnualizedGain />
<HoldingsGain />
<HoldingsGainPercentRealtime>N/A - N/A</HoldingsGainPercentRealtime>
<HoldingsGainRealtime />
<MoreInfo>cnprmiIed</MoreInfo>
<OrderBookRealtime />
<MarketCapitalization>9.2M</MarketCapitalization>
<MarketCapRealtime />
<EBITDA>-34.5M</EBITDA>
<ChangeFromYearLow>+0.18</ChangeFromYearLow>
<PercentChangeFromYearLow>+42.86%</PercentChangeFromYearLow>
<LastTradeRealtimeWithTime>N/A - <b>0.60</b></LastTradeRealtimeWithTime>
<ChangePercentRealtime>N/A - 0.00%</ChangePercentRealtime>
<ChangeFromYearHigh>-2.35</ChangeFromYearHigh>
<PercebtChangeFromYearHigh>-79.66%</PercebtChangeFromYearHigh>
<LastTradeWithTime>Jan 25 - <b>0.60</b></LastTradeWithTime>
<LastTradePriceOnly>0.60</LastTradePriceOnly>
<HighLimit />
<LowLimit />
<DaysRange>N/A - N/A</DaysRange>
<DaysRangeRealtime>N/A - N/A</DaysRangeRealtime>
<FiftydayMovingAverage>0.5639</FiftydayMovingAverage>
<TwoHundreddayMovingAverage>1.4051</TwoHundreddayMovingAverage>
<ChangeFromTwoHundreddayMovingAverage>-0.8051</ChangeFromTwoHundreddayMovingAverage>
<PercentChangeFromTwoHundreddayMovingAverage>-57.30%</PercentChangeFromTwoHundreddayMovingAverage>
<ChangeFromFiftydayMovingAverage>+0.0361</ChangeFromFiftydayMovingAverage>
<PercentChangeFromFiftydayMovingAverage>+6.39%</PercentChangeFromFiftydayMovingAverage>
<Name>Affirmative Insur</Name>
<Notes />
<Open />
<PreviousClose>0.60</PreviousClose>
<PricePaid />
<ChangeinPercent>0.00%</ChangeinPercent>
<PriceSales>0.03</PriceSales>
<PriceBook>0.12</PriceBook>
<ExDividendDate>12-Dec-08</ExDividendDate>
<PERatio />
<DividendPayDate>31-Dec-08</DividendPayDate>
<PERatioRealtime />
<PEGRatio />
<PriceEPSEstimateCurrentYear />
<PriceEPSEstimateNextYear />
<Symbol>AFFM</Symbol>
<SharesOwned />
<ShortRatio>0.20</ShortRatio>
<LastTradeTime>1:34pm</LastTradeTime>
<TickerTrend>&nbsp;======&nbsp;</TickerTrend>
<OneyrTargetPrice>6.00</OneyrTargetPrice>
<Volume>200</Volume>
<HoldingsValue />
<HoldingsValueRealtime />
<YearRange>0.42 - 2.95</YearRange>
<DaysValueChange>- - 0.00%</DaysValueChange>
<DaysValueChangeRealtime>N/A - N/A</DaysValueChangeRealtime>
<StockExchange>NasdaqNM</StockExchange>
<DividendYield />
<PercentChange>0.00%</PercentChange>
</quote>
答案 0 :(得分:2)
此
s.Element("Open") != null
不符合您的想法。如果有一个元素Open
,即使看起来与您的示例中的相同(<Open />
) - 该条件也是如此。元素Open
存在,并且不为空。它只是没有值(或者确切地说,它具有空字符串,""
的值 - 这会导致您的格式异常)。
在where
条款中,您应该将条件更改为
s.Element("Volume").Value != ""
以防止尝试解析空值元素。
快速举例。这个小程序打印的是什么?
var xDoc = XDocument.Parse("<quote><Open /></quote>");
var open = xDoc.Descendants("quote").First().Element("Open");
Console.WriteLine(open == null);
Console.WriteLine(open);
没错。 False
后跟<Open />
。
答案 1 :(得分:2)
您在查询中执行的那些空检查毫无意义,(几乎所有)这些元素都存在于XML中,但其中许多都是空的。您正在尝试解析空字符串,但未能提供错误。您应该给我们一个样本XML,它代表您实际拥有的内容(即,其中包含值)。如果这是您所拥有的,那么您正在执行错误的检查。
我已经重新构建了这样的查询,并且我已经标记了发生异常的位置:
var query =
from quote in doc.Descendants("quote")
let lastTradeDate = (DateTime)quote.Element("LastTradeDate")
where lastTradeDate == targetDate
let symbol = (string)quote.Attribute("symbol")
let open = (double)quote.Element("Open") // EXCEPTION: empty string to a double?
let daysHigh = (double)quote.Element("DaysHigh") // DITTO
let daysLow = (double)quote.Element("DaysLow") // DITTO
let lastTradePriceOnly = (double)quote.Element("LastTradePriceOnly")
let volume = (long)quote.Element("Volume") // no Volume element exists, null check might be appropriate
select new DailyPricingVolDP(symbol, lastTradeDate, open, daysHigh, daysLow, lastTradePriceOnly, volume);