Ошибки форматирования в моем запросе LINQ to XML - PullRequest
1 голос
/ 27 января 2012

Я пытаюсь обработать изломы этого LINQ to XML-запроса данных о фондовом рынке, возвращаемых через yql из yahoo finance. Некоторые из полей имеют либо неправильные данные, либо нулевые значения. Моя текущая ошибка:

Входная строка была в неправильном формате.

Я добавил проверку пустых значений для каждого интересующего меня элемента, но ошибка сохраняется.

Если это поможет, выделенный фрагмент кода, который, по-видимому, выдает исключение, является блоком, содержащим «новую» инициализацию моего объекта точки данных. Если XML прошел проверки в запросе, он выдал бы ошибку, когда в конструктор передаются значения NULL при инициализации 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 - &lt;b&gt;0.60&lt;/b&gt;</LastTradeRealtimeWithTime>
  <ChangePercentRealtime>N/A - 0.00%</ChangePercentRealtime>
  <ChangeFromYearHigh>-2.35</ChangeFromYearHigh>
  <PercebtChangeFromYearHigh>-79.66%</PercebtChangeFromYearHigh>
  <LastTradeWithTime>Jan 25 - &lt;b&gt;0.60&lt;/b&gt;</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>&amp;nbsp;======&amp;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>

Ответы [ 2 ]

2 голосов
/ 27 января 2012

Те нулевые проверки, которые вы делаете в своем запросе, бессмысленны (почти все), эти элементы присутствуют в 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);
2 голосов
/ 27 января 2012

Этот

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 />.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...